Orders & logistics
When you move to Ultineo with years of sales recorded in another system, these endpoints let your migration or sync tool bring the whole history into your shop — customers, orders with their lines, payments, shipments, carrier claims, refused parcels, refunds, returns, loyalty wallet movements and support requests with their messages — keeping the original dates, then read back any record to check it.
Every import follows the shared contract described in Your first API call: an items list, an optional dry_run, and a line-by-line report. Every record is recognised by its external_id — its reference in your former system — so sending it again updates it instead of creating a duplicate.
Endpoints
| Method | Path | Scope | Batch limit |
|---|---|---|---|
| POST | /v1/customer/import | customer:write | 200 customers |
| GET | /v1/customer/import | customer:read | One customer |
| POST | /v1/order/import | order:write | 100 orders |
| GET | /v1/order/import | order:read | One order |
| POST | /v1/payment/import | payment:write | 300 payments |
| GET | /v1/payment/import | payment:read | One payment |
| POST | /v1/shipment/import | shipment:write | 500 shipments |
| GET | /v1/shipment/import | shipment:read | One shipment |
| POST | /v1/shipment/claim | shipment_claim:write | 500 claims |
| GET | /v1/shipment/claim | shipment_claim:read | One claim |
| POST | /v1/shipment/refused | shipment_refused:write | 500 refused parcels |
| GET | /v1/shipment/refused | shipment_refused:read | One refused parcel |
| POST | /v1/refund/import | refund:write | 400 refunds |
| GET | /v1/refund/import | refund:read | One refund |
| POST | /v1/order-return/import | order_return:write | 300 returns |
| GET | /v1/order-return/import | order_return:read | One return |
| POST | /v1/customer-wallet/import | customer_wallet:write | 500 wallet movements |
| GET | /v1/customer-wallet/import | customer_wallet:read | One wallet movement |
| POST | /v1/support-request/import | support_request:write | 25 support requests |
| GET | /v1/support-request/import | support_request:read | One support request |
Import in this order, because each record refers to the previous ones: customers, then orders, then payments and shipments, then refunds, returns, carrier claims, refused parcels, wallet movements and support requests. A record that refers to one not imported yet is refused, with a reason naming the missing reference.
What every resource shares
- Dates (
created_at,placed_at,shipped_at…) are Unix timestamps in seconds. Thecreated_atyou send is kept as the record's original date and is never changed by a later import. When you leave it out, most resources use the closest date they know, such as the order's date. - Links to other records use their
external_id:customer_external_id,order_external_id,shipment_external_id, and so on. - Statuses are checked against the exact values listed below, in lower case. A record withdrawn in your workspace keeps its status: an import never brings it back, and a
noticesays so. - Reading a record:
GETwith?external_id=(its reference in your former system) or?id=(its identifier in your shop). With neither, the call answers400; a record that is not in your shop answers404.
Customers
A customer is a buyer of your shop, with a billing and a delivery address. Import customers first: every other record of this page refers to them.
Import customers
POST /v1/customer/import
| Field | Type | Required | Description |
|---|---|---|---|
external_id | string | Yes | Your reference for the customer, up to 50 characters. |
created_at | integer | Yes | The date the account was created, in Unix seconds. Not more than one day in the future. |
status | string | No | activated (default), active (stored as activated), suspended or deleted. |
type | string | No | Up to 50 characters. Defaults to individual. |
first_name | string | No | Up to 150 characters. |
last_name | string | No | Up to 150 characters. |
name | string | No | Up to 190 characters. Defaults to the first and last names. |
company | string | No | Up to 190 characters. |
email | string | No | Up to 200 characters. |
email_verified | boolean | No | true when the address was verified. |
phone | string | No | Up to 50 characters. |
password_hash | string | No | The customer's password hash from your former system, up to 190 characters. Never returned. |
note | string | No | An internal note. |
billing | object | No | The billing address (see below). Left empty, it is filled from the delivery address, with a notice. |
delivery | object | No | The delivery address (see below). |
previous | object | No | The values you sent on your previous import of this customer, with the same keys. A contact or address field that differs from it was changed in your shop since, and is kept. |
Each address holds line1, line2 (up to 190 characters), city (up to 120), postal_code (up to 30), state (up to 120) and country_iso — a two-letter country code such as fr.
curl https://api.ultineo.com/v1/customer/import \
-H "Authorization: Bearer sk-project-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"external_id": "C1001",
"created_at": 1717236000,
"first_name": "Claire",
"last_name": "Martin",
"email": "claire.martin@example.com",
"email_verified": true,
"phone": "+33 6 12 34 56 78",
"delivery": {
"line1": "12 rue des Lilas",
"line2": "",
"city": "Lyon",
"postal_code": "69003",
"state": "",
"country_iso": "fr"
}
}
]
}' {
"code": 200,
"title": "OK",
"response": {
"object": "list",
"resource": "customer",
"dry_run": false,
"data": [
{ "index": 0, "external_id": "C1001", "action": "created", "id": "cust_c3e9a1074b5d28f6e0a7", "code": null, "title": null, "reason": null, "notice": ["blank billing initialized from delivery"] }
],
"created": 1,
"updated": 0,
"unchanged": 0,
"refused": 0,
"total": 1
}
} Read a customer
GET /v1/customer/import
| Parameter | In | Description |
|---|---|---|
external_id | query | The customer's reference in your former system. |
id | query | Its identifier in your shop, prefixed cust_. A value without that prefix is read as an external_id. |
With neither, the call answers 400 Name the customer to read: ?external_id=… or /v1/customer/cust_….; an unknown customer answers 404 Customer not found.
curl "https://api.ultineo.com/v1/customer/import?external_id=C1001" \
-H "Authorization: Bearer sk-project-YOUR_KEY" {
"code": 200,
"title": "OK",
"response": {
"id": "cust_c3e9a1074b5d28f6e0a7",
"object": "customer",
"external_id": "C1001",
"status": "activated",
"type": "individual",
"first_name": "Claire",
"last_name": "Martin",
"name": "Claire Martin",
"company": "",
"email": "claire.martin@example.com",
"email_verified": true,
"phone": "+33 6 12 34 56 78",
"has_password": false,
"note": "",
"billing": { "line1": "12 rue des Lilas", "line2": "", "city": "Lyon", "postal_code": "69003", "state": "", "country_iso": "fr" },
"delivery": { "line1": "12 rue des Lilas", "line2": "", "city": "Lyon", "postal_code": "69003", "state": "", "country_iso": "fr" },
"created_at": 1717236000,
"updated_at": 1791745200
}
} The password itself is never returned; has_password says whether one is set.
Orders
An order is imported with all its lines in one item, and keeps its original dates. Totals are stored as you send them and are never recalculated: when the total does not match the articles, delivery and discount amounts, the report tells you in amount_check.
Import orders
POST /v1/order/import
| Field | Type | Required | Description |
|---|---|---|---|
external_id | string | Yes | Your reference for the order, up to 50 characters. |
customer_external_id | string | For a new order | The external_id of an already imported customer. |
order_number | string | No | The order number shown to the customer, up to 50 characters. reference is accepted as an alias. |
status | string | No | The commercial status: pending, paid, preparing, shipped, delivered, canceled or refunded. A status is never moved back: a status earlier in that list than the stored one is not applied. |
si_code | string | No | The code of the store the order was placed on, up to 10 characters. |
currency | string | No | A currency code of 3 to 10 letters, such as EUR. |
channel | string | No | online, in_store, phone or other. |
articles_amount | number or string | No | The total of the articles. |
delivery_amount | number or string | No | The delivery charge. |
discount_amount | number or string | No | The discount granted. |
total_amount | number or string | No | The amount paid. |
discount_code | string | No | The discount code used, up to 50 characters. |
note | string | No | An internal note. |
placed_at | integer | No | The date the order was placed, in Unix seconds. |
delivered_at | integer | No | The delivery date, in Unix seconds. |
created_at | integer | No | The original creation date. Defaults to placed_at. |
items | array | No | The order lines (see below). |
Each entry of items:
| Field | Type | Required | Description |
|---|---|---|---|
external_id | string | Yes | Your reference for the line, unique in the order. |
sku | string | No | The product's SKU, up to 120 characters. The line is linked to the product of your catalog with that SKU. |
product | string | No | The product's identifier in your shop (prod_…), instead of the SKU. |
name | string | No | The product name as sold, up to 190 characters. |
grade | string | No | The condition grade sold, up to 120 characters. |
serial | string | No | The serial number of the item sold, up to 190 characters. |
quantity | integer | No | A positive whole number. |
unit_price | number or string | No | The unit price. |
line_total | number or string | No | The line total. |
delivery_amount | number or string | No | The delivery charge of the line. |
warranty_amount | number or string | No | The warranty charge of the line. |
currency | string | No | Defaults to the order's currency. |
created_at | integer | No | The line's original date. |
An order is saved with all its lines or not at all: one invalid line refuses the whole order. Lines you leave out of a later import are kept.
Each accepted entry of the report adds:
| Field | Type | Description |
|---|---|---|
items | object | The number of lines created, updated and unchanged. |
items_detail | array | One entry per line: its external_id, action and id. |
amount_check | object or null | null when the amounts agree; otherwise expected_from_fields (articles + delivery − discount), total_amount, difference and items_line_total, as decimal strings. |
curl https://api.ultineo.com/v1/order/import \
-H "Authorization: Bearer sk-project-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"external_id": "ORD-10458",
"customer_external_id": "C1001",
"order_number": "10458",
"status": "delivered",
"currency": "EUR",
"channel": "online",
"articles_amount": "459.00",
"delivery_amount": "0.00",
"discount_amount": "15.00",
"total_amount": "444.00",
"discount_code": "SPRING15",
"placed_at": 1781258400,
"delivered_at": 1781431200,
"items": [
{ "external_id": "ORD-10458-1", "sku": "IP13-128-MID", "name": "iPhone 13 128 GB Midnight", "grade": "very_good", "quantity": 1, "unit_price": "459.00", "line_total": "459.00" }
]
}
]
}' {
"code": 200,
"title": "OK",
"response": {
"object": "list",
"resource": "order",
"dry_run": false,
"data": [
{
"index": 0,
"external_id": "ORD-10458",
"action": "created",
"id": "ordr_5e0a8c2f71d94b36e1c8",
"code": null,
"title": null,
"reason": null,
"notice": [],
"items": { "created": 1, "updated": 0, "unchanged": 0 },
"items_detail": [
{ "external_id": "ORD-10458-1", "action": "created", "id": "oitm_8a3f0e6c2d1b47e95c20" }
],
"amount_check": null
}
],
"created": 1,
"updated": 0,
"unchanged": 0,
"refused": 0,
"total": 1
}
} Read an order
GET /v1/order/import
| Parameter | In | Description |
|---|---|---|
external_id | query | The order's reference in your former system. |
id | query | Its identifier in your shop, prefixed ordr_. |
With neither, the call answers 400 Missing required parameter: external_id.; an unknown order answers 404 Order not found.
curl "https://api.ultineo.com/v1/order/import?external_id=ORD-10458" \
-H "Authorization: Bearer sk-project-YOUR_KEY" {
"code": 200,
"title": "OK",
"response": {
"id": "ordr_5e0a8c2f71d94b36e1c8",
"object": "order",
"external_id": "ORD-10458",
"project": "proj_5a91c7e03d2b48f6a1e9",
"status": "activated",
"commercial_status": "delivered",
"reference": "10458",
"customer": "cust_c3e9a1074b5d28f6e0a7",
"customer_external_id": "C1001",
"si_code": "",
"currency": "EUR",
"channel": "online",
"articles_amount": "459.00",
"delivery_amount": "0.00",
"discount_amount": "15.00",
"discount_code": "SPRING15",
"total_amount": "444.00",
"note": "",
"placed_at": 1781258400,
"delivered_at": 1781431200,
"ship_before_at": 0,
"created_at": 1781258400,
"updated_at": 1791745200,
"items": [
{
"id": "oitm_8a3f0e6c2d1b47e95c20",
"object": "order_item",
"external_id": "ORD-10458-1",
"status": "activated",
"product": "prod_a81f3c6e0b2d49e7c5f0",
"sku": "IP13-128-MID",
"name": "iPhone 13 128 GB Midnight",
"grade": "very_good",
"serial": "",
"quantity": 1,
"unit_price": "459.00",
"line_total": "459.00",
"delivery_amount": "0.00",
"warranty_amount": "0.00",
"currency": "EUR",
"created_at": 1781258400,
"updated_at": 1791745200
}
]
}
} commercial_status is the order's commercial status; status is the state of the record itself. ship_before_at is the shipping deadline your shop computes; it is read-only.
Payments
A payment settles an order. Its gateway (the payment processor) and its method (how the buyer paid) are two separate fields.
Import payments
POST /v1/payment/import
| Field | Type | Required | Description |
|---|---|---|---|
external_id | string | Yes | Your reference for the payment, up to 50 characters. |
order_external_id | string | Yes | The external_id of an already imported order. |
created_at | integer | Yes | The payment's original date, in Unix seconds. Not more than one day in the future. |
status | string | No | pending (default), paid, refunded, canceled or deleted. |
amount | number or string | No | The amount paid. Zero or more, with up to 2 decimals. |
fee_amount | number or string | No | The processing fee. |
refunded_amount | number or string | No | The amount refunded. |
refunds | array | No | The refunds of this payment, each { "external_id", "amount" }. When sent, their sum replaces refunded_amount. |
currency | string | No | Up to 10 characters, such as EUR. |
method | string | No | How the buyer paid, such as card, up to 50 characters. |
gateway | string | No | The payment processor, up to 50 characters. |
reference | string | No | The processor's transaction reference, up to 190 characters. |
session_reference | string | No | The processor's checkout session reference, up to 190 characters. |
paid_at | integer | No | The date the payment succeeded, in Unix seconds. |
curl https://api.ultineo.com/v1/payment/import \
-H "Authorization: Bearer sk-project-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"external_id": "PAY-77120",
"order_external_id": "ORD-10458",
"created_at": 1781258460,
"status": "paid",
"amount": "444.00",
"fee_amount": "6.66",
"currency": "EUR",
"method": "card",
"gateway": "stripe",
"reference": "pi_3PZ0d2KJ8nA1",
"paid_at": 1781258460
}
]
}' {
"code": 200,
"title": "OK",
"response": {
"object": "list",
"resource": "payment",
"dry_run": false,
"data": [
{ "index": 0, "external_id": "PAY-77120", "action": "created", "id": "paym_2b7d9e04c1a35f8e6d91", "code": null, "title": null, "reason": null, "notice": [] }
],
"created": 1,
"updated": 0,
"unchanged": 0,
"refused": 0,
"total": 1
}
} Read a payment
GET /v1/payment/import
| Parameter | In | Description |
|---|---|---|
external_id | query | The payment's reference in your former system. |
id | query | Its identifier in your shop, prefixed paym_. A value without that prefix is read as an external_id. |
With neither, the call answers 400 Name the payment to read: ?external_id=… or /v1/payment/paym_….; an unknown payment answers 404 Payment not found.
curl "https://api.ultineo.com/v1/payment/import?external_id=PAY-77120" \
-H "Authorization: Bearer sk-project-YOUR_KEY" {
"code": 200,
"title": "OK",
"response": {
"id": "paym_2b7d9e04c1a35f8e6d91",
"object": "payment",
"external_id": "PAY-77120",
"status": "paid",
"order_id": "ordr_5e0a8c2f71d94b36e1c8",
"order_external_id": "ORD-10458",
"amount": "444.00",
"fee_amount": "6.66",
"refunded_amount": "0.00",
"currency": "EUR",
"method": "card",
"gateway": "stripe",
"reference": "pi_3PZ0d2KJ8nA1",
"session_reference": "",
"paid_at": 1781258460,
"created_at": 1781258460,
"updated_at": 1791745200
}
} Shipments
A shipment is a parcel sent for an order, with its carrier and tracking number. Its status follows its dates: delivered once delivered_at is set, shipped once shipped_at is set, pending otherwise.
Import shipments
POST /v1/shipment/import
| Field | Type | Required | Description |
|---|---|---|---|
external_id | string | Yes | Your reference for the parcel, up to 50 characters. |
order_external_id | string | Yes | The external_id of an already imported order. |
carrier_name | string | No | The carrier, up to 190 characters. |
tracking_number | string | No | Up to 190 characters. |
tracking_url | string | No | The tracking page, a full https:// address of up to 500 characters. |
recipient_name | string | No | Up to 190 characters. |
note | string | No | Up to 2,000 characters. |
shipped_at | integer | No | The date the parcel left, in Unix seconds. |
delivered_at | integer | No | The delivery date. Left out, the order's delivery date is used. |
created_at | integer | No | The original date. Defaults to shipped_at. |
curl https://api.ultineo.com/v1/shipment/import \
-H "Authorization: Bearer sk-project-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"external_id": "SHP-20931",
"order_external_id": "ORD-10458",
"carrier_name": "Colissimo",
"tracking_number": "6A23456789012",
"recipient_name": "Claire Martin",
"shipped_at": 1781334000,
"delivered_at": 1781431200
}
]
}' {
"code": 200,
"title": "OK",
"response": {
"object": "list",
"resource": "shipment",
"dry_run": false,
"data": [
{ "index": 0, "external_id": "SHP-20931", "action": "created", "id": "ship_9c1e5a7f02d34b86e0a3", "code": null, "title": null, "reason": null, "notice": [] }
],
"created": 1,
"updated": 0,
"unchanged": 0,
"refused": 0,
"total": 1
}
} Read a shipment
GET /v1/shipment/import
| Parameter | In | Description |
|---|---|---|
external_id | query | The parcel's reference in your former system. |
id | query | Its identifier in your shop, prefixed ship_. |
With neither, the call answers 400 Missing required parameter: external_id.; an unknown parcel answers 404 Shipment not found.
curl "https://api.ultineo.com/v1/shipment/import?external_id=SHP-20931" \
-H "Authorization: Bearer sk-project-YOUR_KEY" {
"code": 200,
"title": "OK",
"response": {
"id": "ship_9c1e5a7f02d34b86e0a3",
"object": "shipment",
"external_id": "SHP-20931",
"status": "delivered",
"order": "ordr_5e0a8c2f71d94b36e1c8",
"carrier_name": "Colissimo",
"tracking_number": "6A23456789012",
"recipient_name": "Claire Martin",
"note": "",
"shipped_at": 1781334000,
"delivered_at": 1781431200,
"created_at": 1781334000,
"updated_at": 1791745200
}
} Carrier claims
A carrier claim is a dispute opened with the carrier about a parcel — lost, damaged, held by customs or not collected.
Import carrier claims
POST /v1/shipment/claim
| Field | Type | Required | Description |
|---|---|---|---|
external_id | string | Yes | Your reference for the claim, up to 50 characters. |
shipment_external_id | string | Yes | The external_id of an already imported shipment. The order is taken from the parcel. |
type | string | Yes | lost, damaged, customs or not_collected. |
status | string | No | new (default), open, certified_delivered, certified_lost or canceled. A claim canceled in your shop stays canceled. |
reference | string | No | The carrier's claim reference, up to 190 characters. |
note | string | No | Up to 2,000 characters. |
opened_at | integer | No | The date the claim was opened, in Unix seconds. |
settled_at | integer | No | The date it was settled. |
created_at | integer | No | The original date. Defaults to opened_at. |
Note — If your shop has never opened its Claims page, the import answers
422and asks you to open that page once in your workspace, then replay the batch.
curl https://api.ultineo.com/v1/shipment/claim \
-H "Authorization: Bearer sk-project-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"external_id": "CLM-0081",
"shipment_external_id": "SHP-20931",
"type": "damaged",
"status": "open",
"reference": "COL-2026-55102",
"opened_at": 1781517600
}
]
}' {
"code": 200,
"title": "OK",
"response": {
"object": "list",
"resource": "shipment_claim",
"dry_run": false,
"data": [
{ "index": 0, "external_id": "CLM-0081", "action": "created", "id": "clai_4f8b2d6e01a93c75e2b0", "code": null, "title": null, "reason": null, "notice": [] }
],
"created": 1,
"updated": 0,
"unchanged": 0,
"refused": 0,
"total": 1
}
} Read a carrier claim
GET /v1/shipment/claim
| Parameter | In | Description |
|---|---|---|
external_id | query | The claim's reference in your former system. |
id | query | Its identifier in your shop, prefixed clai_. |
With neither, the call answers 400 Missing required parameter: external_id.; an unknown claim answers 404 Claim not found.
curl "https://api.ultineo.com/v1/shipment/claim?external_id=CLM-0081" \
-H "Authorization: Bearer sk-project-YOUR_KEY" {
"code": 200,
"title": "OK",
"response": {
"id": "clai_4f8b2d6e01a93c75e2b0",
"object": "shipment_claim",
"external_id": "CLM-0081",
"status": "open",
"shipment": "ship_9c1e5a7f02d34b86e0a3",
"order": "ordr_5e0a8c2f71d94b36e1c8",
"type": "damaged",
"reference": "COL-2026-55102",
"note": "",
"opened_at": 1781517600,
"settled_at": 0,
"created_at": 1781517600,
"updated_at": 1791745200
}
} Refused parcels
A refused parcel is a shipment the recipient refused, on its way back to your warehouse.
Import refused parcels
POST /v1/shipment/refused
| Field | Type | Required | Description |
|---|---|---|---|
external_id | string | Yes | Your reference for the refusal, up to 50 characters. |
shipment_external_id | string | Yes | The external_id of an already imported shipment. |
status | string | No | awaiting_delivery (default), warehouse_received or canceled. A refusal canceled in your shop stays canceled. |
return_number | string | No | The return number, up to 190 characters. |
note | string | No | Up to 2,000 characters. |
refused_at | integer | No | The date the parcel was refused, in Unix seconds. |
received_at | integer | No | The date it was received back at the warehouse. |
created_at | integer | No | The original date. Defaults to refused_at. |
Note — If your shop has never opened its Refused page, the import answers
422and asks you to open that page once in your workspace, then replay the batch.
curl https://api.ultineo.com/v1/shipment/refused \
-H "Authorization: Bearer sk-project-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"external_id": "REF-0042",
"shipment_external_id": "SHP-20931",
"status": "warehouse_received",
"return_number": "RET-55871",
"refused_at": 1781431200,
"received_at": 1781690400
}
]
}' {
"code": 200,
"title": "OK",
"response": {
"object": "list",
"resource": "shipment_refused",
"dry_run": false,
"data": [
{ "index": 0, "external_id": "REF-0042", "action": "created", "id": "refu_7a0c3e9b51d24f68a0e7", "code": null, "title": null, "reason": null, "notice": [] }
],
"created": 1,
"updated": 0,
"unchanged": 0,
"refused": 0,
"total": 1
}
} Read a refused parcel
GET /v1/shipment/refused
| Parameter | In | Description |
|---|---|---|
external_id | query | The refusal's reference in your former system. |
id | query | Its identifier in your shop, prefixed refu_. |
With neither, the call answers 400 Missing required parameter: external_id.; an unknown refusal answers 404 Refusal not found.
curl "https://api.ultineo.com/v1/shipment/refused?external_id=REF-0042" \
-H "Authorization: Bearer sk-project-YOUR_KEY" {
"code": 200,
"title": "OK",
"response": {
"id": "refu_7a0c3e9b51d24f68a0e7",
"object": "shipment_refused",
"external_id": "REF-0042",
"status": "warehouse_received",
"shipment": "ship_9c1e5a7f02d34b86e0a3",
"order": "ordr_5e0a8c2f71d94b36e1c8",
"return_number": "RET-55871",
"note": "",
"refused_at": 1781431200,
"received_at": 1781690400,
"created_at": 1781431200,
"updated_at": 1791745200
}
} Refunds
A refund returns money to the buyer for an order, optionally against one of its payments.
Import refunds
POST /v1/refund/import
| Field | Type | Required | Description |
|---|---|---|---|
external_id | string | Yes | Your reference for the refund, up to 50 characters. |
order_external_id | string | Yes | The external_id of an already imported order. |
payment_external_id | string | No | The external_id of the refunded payment. Required when amount is above zero, unless status is mistake. |
customer_external_id | string | No | The external_id of the refunded customer. |
amount | number or string | No | The amount refunded. Zero or more, with up to 2 decimals. |
currency | string | No | Up to 10 characters, such as EUR. |
reason | string | No | full_order, partial, priority_shipping, out_of_delivery_area, package_lost, returned_to_warehouse, no_service_for_country, return_voucher_converted, commercial_gesture or out_of_stock. |
status | string | No | in_progress (default), finished or mistake. |
note | string | No | Up to 2,000 characters. |
refunded_at | integer | No | The date of the refund, in Unix seconds. |
created_at | integer | No | The original date. Defaults to refunded_at. |
Note — The item field
reasonis the reason for the refund. Do not confuse it with thereasonof a refused entry in the import report.
Important — A refund above zero that is not a
mistakecounts against its payment. That payment must be paid or refunded, the refund'scurrencymust be the payment's, and all the refunds of one payment, pending ones included, cannot exceed it. Otherwise the entry is refused with422and areasonsuch asTotal refunds, including pending refunds, cannot exceed the original payment.
curl https://api.ultineo.com/v1/refund/import \
-H "Authorization: Bearer sk-project-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"external_id": "RFD-3307",
"order_external_id": "ORD-10458",
"payment_external_id": "PAY-77120",
"amount": "40.00",
"currency": "EUR",
"reason": "commercial_gesture",
"status": "finished",
"refunded_at": 1781604000
}
]
}' {
"code": 200,
"title": "OK",
"response": {
"object": "list",
"resource": "refund",
"dry_run": false,
"data": [
{ "index": 0, "external_id": "RFD-3307", "action": "created", "id": "rfnd_0e6b4a2c93f15d78b4c1", "code": null, "title": null, "reason": null, "notice": [] }
],
"created": 1,
"updated": 0,
"unchanged": 0,
"refused": 0,
"total": 1
}
} Read a refund
GET /v1/refund/import
| Parameter | In | Description |
|---|---|---|
external_id | query | The refund's reference in your former system. |
id | query | Its identifier in your shop, prefixed rfnd_. |
With neither, the call answers 400 Missing required parameter: external_id.; an unknown refund answers 404 Refund not found.
curl "https://api.ultineo.com/v1/refund/import?external_id=RFD-3307" \
-H "Authorization: Bearer sk-project-YOUR_KEY" {
"code": 200,
"title": "OK",
"response": {
"id": "rfnd_0e6b4a2c93f15d78b4c1",
"object": "refund",
"external_id": "RFD-3307",
"status": "finished",
"order": "ordr_5e0a8c2f71d94b36e1c8",
"payment": "paym_2b7d9e04c1a35f8e6d91",
"customer": "",
"reason": "commercial_gesture",
"amount": "40.00",
"currency": "EUR",
"note": "",
"refunded_at": 1781604000,
"created_at": 1781604000,
"updated_at": 1791745200
}
} Order returns
An order return is an item a customer sends back — a withdrawal, a warranty case or a wrong item — and how it was resolved.
Import order returns
POST /v1/order-return/import
| Field | Type | Required | Description |
|---|---|---|---|
external_id | string | Yes | Your reference for the return, up to 50 characters. |
order_external_id | string | Yes | The external_id of an already imported order. |
customer_external_id | string | Yes | The external_id of an already imported customer. |
order_item_external_id | string | No | The external_id of the returned line of that order. |
type | string | No | withdrawal, warranty, wrong_item or other (default). |
resolution | string | No | exchange or refund. Set when the return is created. |
status | string | No | One of your shop's return statuses — by default requested, validated, icloud_check, icloud_verified, parcel_waiting, received, verified, complete or incident. Defaults to the first one. A status is never moved back along that flow. deleted withdraws a return already imported. |
serial | string | No | The serial number of the returned item: 1 to 50 letters, digits or dashes. |
carrier_name | string | No | Up to 190 characters. |
tracking_number | string | No | Up to 190 characters. |
label_url | string | No | The return label, a full https:// address of up to 500 characters. |
support_request | string | No | The identifier in your shop (sprq_…) of the related support request. |
received_at | integer | No | The date the item was received, in Unix seconds. |
completed_at | integer | No | The date the return was completed. |
created_at | integer | No | The original date. Defaults to received_at. |
curl https://api.ultineo.com/v1/order-return/import \
-H "Authorization: Bearer sk-project-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"external_id": "RTN-1190",
"order_external_id": "ORD-10458",
"customer_external_id": "C1001",
"order_item_external_id": "ORD-10458-1",
"type": "withdrawal",
"resolution": "refund",
"status": "received",
"carrier_name": "Colissimo",
"tracking_number": "8R00112233445",
"received_at": 1781776800
}
]
}' {
"code": 200,
"title": "OK",
"response": {
"object": "list",
"resource": "order_return",
"dry_run": false,
"data": [
{ "index": 0, "external_id": "RTN-1190", "action": "created", "id": "ortn_6d2a0f8c41e93b57d1a8", "code": null, "title": null, "reason": null, "notice": [] }
],
"created": 1,
"updated": 0,
"unchanged": 0,
"refused": 0,
"total": 1
}
} Read an order return
GET /v1/order-return/import
| Parameter | In | Description |
|---|---|---|
external_id | query | The return's reference in your former system. |
id | query | Its identifier in your shop, prefixed ortn_. |
With neither, the call answers 400 Missing required parameter: external_id.; an unknown return answers 404 Order return not found.
curl "https://api.ultineo.com/v1/order-return/import?external_id=RTN-1190" \
-H "Authorization: Bearer sk-project-YOUR_KEY" {
"code": 200,
"title": "OK",
"response": {
"id": "ortn_6d2a0f8c41e93b57d1a8",
"object": "order_return",
"external_id": "RTN-1190",
"status": "received",
"type": "withdrawal",
"resolution": "refund",
"customer": "cust_c3e9a1074b5d28f6e0a7",
"order": "ordr_5e0a8c2f71d94b36e1c8",
"order_item": "oitm_8a3f0e6c2d1b47e95c20",
"support_request": "",
"serial": "",
"carrier_name": "Colissimo",
"tracking_number": "8R00112233445",
"label_url": "",
"received_at": 1781776800,
"completed_at": 0,
"created_at": 1781776800,
"updated_at": 1791745200
}
} Customer wallet
A wallet movement is a line of a customer's loyalty wallet: points earned on a purchase, a referral or a review, or points spent.
Import wallet movements
POST /v1/customer-wallet/import
| Field | Type | Required | Description |
|---|---|---|---|
external_id | string | Yes | Your reference for the movement, up to 50 characters. |
customer_external_id | string | Yes | The external_id of an already imported customer. |
order_external_id | string | No | The external_id of the related order. |
points | number or string | No | The points, positive for a credit or negative for a debit, with up to 4 decimals. |
reason | string | No | purchase, referral, activity, review, goodwill or conversion. |
status | string | No | credited (default), pending or cancelled. |
note | string | No | A one-line note, up to 190 characters. |
earned_at | integer | No | The date the points were earned, in Unix seconds. |
created_at | integer | No | The original date. Defaults to earned_at. |
curl https://api.ultineo.com/v1/customer-wallet/import \
-H "Authorization: Bearer sk-project-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"external_id": "WAL-55210",
"customer_external_id": "C1001",
"order_external_id": "ORD-10458",
"points": "44.4",
"reason": "purchase",
"status": "credited",
"earned_at": 1781431200
}
]
}' {
"code": 200,
"title": "OK",
"response": {
"object": "list",
"resource": "customer_wallet",
"dry_run": false,
"data": [
{ "index": 0, "external_id": "WAL-55210", "action": "created", "id": "cwal_3b9e1d7a05c42f86e3d2", "code": null, "title": null, "reason": null, "notice": [] }
],
"created": 1,
"updated": 0,
"unchanged": 0,
"refused": 0,
"total": 1
}
} Read a wallet movement
GET /v1/customer-wallet/import
| Parameter | In | Description |
|---|---|---|
external_id | query | The movement's reference in your former system. |
id | query | Its identifier in your shop, prefixed cwal_. |
With neither, the call answers 400 Missing required parameter: external_id.; an unknown movement answers 404 Wallet entry not found.
curl "https://api.ultineo.com/v1/customer-wallet/import?external_id=WAL-55210" \
-H "Authorization: Bearer sk-project-YOUR_KEY" {
"code": 200,
"title": "OK",
"response": {
"id": "cwal_3b9e1d7a05c42f86e3d2",
"object": "customer_wallet_entry",
"external_id": "WAL-55210",
"status": "credited",
"customer": "cust_c3e9a1074b5d28f6e0a7",
"order": "ordr_5e0a8c2f71d94b36e1c8",
"reason": "purchase",
"points": "44.4000",
"note": "",
"earned_at": 1781431200,
"created_at": 1781431200,
"updated_at": 1791745200
}
} Support requests
A support request is a customer's question or after-sales case, imported with its thread of messages.
Import support requests
POST /v1/support-request/import
| Field | Type | Required | Description |
|---|---|---|---|
external_id | string | Yes | Your reference for the request, up to 50 characters. |
customer_external_id | string | Yes | The external_id of an already imported customer. |
order_external_id | string | No | The external_id of the related order. |
order_item_external_id | string | No | The external_id of the related line. Requires order_external_id. |
category | string | No | order or device. Send it together with topic. |
topic | string | No | The subject, from the list of its category (see below). |
status | string | No | open (default), answered, waiting or closed. |
message | string | No | The opening message, up to 16,000 characters. |
answered_at | integer | No | The date of the first answer, in Unix seconds. |
created_at | integer | No | The original date. Defaults to the order's date. |
messages | array | No | The messages of the thread (see below). |
Topics of the order category: package_not_arrived, missing_item, missing_accessory, wrong_model, cancel_order, item_problem, withdrawal, customs_invoice, voucher_refund, delivery, delivery_problem, payment, refund, claim, returned_item, account, order_general, other.
Topics of the device category: slow, no_start, blocking, photo_video, no_flash, screen_color, screen_flash, screen_pixels, battery, battery_80, no_charge, cable, no_sound_call, geolocation, screen_lock, screen_fixed, network, vibrator, black_screen, scratched, button, not_listed.
Each entry of messages:
| Field | Type | Required | Description |
|---|---|---|---|
external_id | string | Yes | Your reference for the message, unique in the batch. |
text | string | Yes | The message, up to 16,000 characters. |
author | string | No | customer (default) or shop. |
status | string | No | activated or deleted. |
created_at | integer | No | The date of the message. Defaults to the request's date. |
A request is saved with all its messages or not at all. Messages you leave out of a later import are kept.
Each accepted entry of the report adds messages (the number of messages created, updated and unchanged) and messages_detail (one entry per message: its external_id, action and id).
curl https://api.ultineo.com/v1/support-request/import \
-H "Authorization: Bearer sk-project-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"external_id": "SUP-4402",
"customer_external_id": "C1001",
"order_external_id": "ORD-10458",
"category": "device",
"topic": "battery",
"status": "closed",
"message": "The battery drains faster than expected.",
"created_at": 1782036000,
"answered_at": 1782046800,
"messages": [
{ "external_id": "SUP-4402-1", "author": "shop", "text": "Thank you, a prepaid return label is on its way.", "created_at": 1782046800 }
]
}
]
}' {
"code": 200,
"title": "OK",
"response": {
"object": "list",
"resource": "support_request",
"dry_run": false,
"data": [
{
"index": 0,
"external_id": "SUP-4402",
"action": "created",
"id": "sprq_1c7e3a9f50b24d68c1e5",
"code": null,
"title": null,
"reason": null,
"notice": [],
"messages": { "created": 1, "updated": 0, "unchanged": 0 },
"messages_detail": [
{ "external_id": "SUP-4402-1", "action": "created", "id": "spmg_8e2b0d4a61f37c95e2b4" }
]
}
],
"created": 1,
"updated": 0,
"unchanged": 0,
"refused": 0,
"total": 1
}
} Read a support request
GET /v1/support-request/import
| Parameter | In | Description |
|---|---|---|
external_id | query | The request's reference in your former system. |
id | query | Its identifier in your shop, prefixed sprq_. |
With neither, the call answers 400 Missing required parameter: external_id.; an unknown request answers 404 Support request not found.
curl "https://api.ultineo.com/v1/support-request/import?external_id=SUP-4402" \
-H "Authorization: Bearer sk-project-YOUR_KEY" {
"code": 200,
"title": "OK",
"response": {
"id": "sprq_1c7e3a9f50b24d68c1e5",
"object": "support_request",
"external_id": "SUP-4402",
"project": "proj_5a91c7e03d2b48f6a1e9",
"status": "closed",
"category": "device",
"topic": "battery",
"customer": "cust_c3e9a1074b5d28f6e0a7",
"order": "ordr_5e0a8c2f71d94b36e1c8",
"order_item": "",
"message": "The battery drains faster than expected.",
"answered_at": 1782046800,
"created_at": 1782036000,
"updated_at": 1791745200,
"messages": [
{
"id": "spmg_8e2b0d4a61f37c95e2b4",
"object": "support_message",
"external_id": "SUP-4402-1",
"status": "activated",
"author": "shop",
"text": "Thank you, a prepaid return label is on its way.",
"created_at": 1782046800,
"updated_at": 1791745200
}
]
}
} The thread is returned in date order, including the messages written in your workspace (their external_id is empty).
Note — These endpoints do not list, search or delete records, and do not trigger actions: cancelling an order, issuing a refund, creating a shipping label or contacting a carrier are done in your workspace.