For your own system – e.g. an ERP, a warehouse system or a webshop we don't have a ready-made integration for. The system sends orders to fragtr, can show your shipping methods in its own checkout, and gets the tracking number back once the order is booked.
fco_…). It is shown only once – create a new one under the webshop if you lose it.Authorization: Bearer fco_…All URLs start with https://fragtr.dk/api/v1/shop. Data is sent and received as JSON.
| Request | What it does |
|---|---|
POST /orders | Create an order – or update it if it has not been booked yet (same order_id). |
GET /orders/{order_id} | Status, booking and tracking number. |
DELETE /orders/{order_id} | The order was cancelled on your side – moved to Ignored (if it has not been booked). |
GET /methods | Your visible shipping methods. |
POST /rates | Shipping options and prices for checkout based on country, weight and cart. |
POST https://fragtr.dk/api/v1/shop/orders
Authorization: Bearer fco_…
Content-Type: application/json
{
"order_id": "SO-1001", // your own id (required, unique)
"number": "1001", // shown in fragtr and used as reference
"ordered_at": "2026-10-24T10:30:00Z",
"shipping_method": "fragtr-12", // code from /rates or /methods (optional)
"currency": "DKK",
"total": 800.00, // value of the goods – used for customs outside the EU
"receiver": {
"name": "Bergen Interiør AS", "contact": "Ola Nordmann",
"street": "Karl Johans gate 12", "street2": "", "zip": "0162", "city": "Oslo",
"country": "NO", "email": "ola@bergen.no", "phone": "+47 22 00 00 00"
},
"items": [
{"name": "Bordlampe messing", "qty": 2, "price": 400.00, "weight_kg": 1.1,
"sku": "L-1", "hs_code": "940520", "origin_country": "DK"}
]
}
Response 201 (new) or 200 (updated):
{"order": {"order_id": "SO-1001", "number": "1001", "status": "new", "shipping_method": "fragtr-12", "booking": null}}
order_id and the receiver's name, street, zip, city and country (two letters, e.g. DK).weight_kg can be sent for the whole order – otherwise we add up the weight of the items.hs_code and origin_country are used for the commercial invoice when the package leaves the EU.new, hold (on hold), booked or ignored. A booked order cannot be changed (409).The order appears under My bookings → Webshop orders. If it has a shipping_method, it can be booked with one click – otherwise you choose a rate in fragtr.
Call /rates when the customer chooses shipping. The response contains your own shipping methods with the prices you have set up – only those that cover the country, weight and cart.
POST https://fragtr.dk/api/v1/shop/rates
Authorization: Bearer fco_…
{"country": "NO", "items": [{"qty": 2, "price": 400.00, "weight_kg": 1.1}]}
{"rates": [
{"code": "fragtr-12", "name": "Levering til døren",
"description": "1–3 hverdage · Told og moms betales af modtageren ved levering",
"price": 149.0, "currency": "DKK"}
]}
Store the selected code and send it as shipping_method when the order is sent to fragtr.
If you have set a webhook, fragtr sends a POST as soon as the order is booked and the tracking number is available:
POST https://jeres-system.dk/fragtr/webhook
X-Fragtr-Event: order.shipped
X-Fragtr-Timestamp: 1792700000
X-Fragtr-Signature: sha256=5d1c…
{"event": "order.shipped", "sent_at": "2026-10-24T11:02:00+00:00",
"data": {"order_id": "SO-1001", "tracking_number": "1Z999AA10123456784",
"tracking_url": "https://www.ups.com/track?tracknum=1Z999AA10123456784", "carrier": "UPS"}}
The signature is HMAC-SHA256 of "{timestamp}.{body}" using the order system's key (fco_…). Respond with 2xx within 8 seconds – otherwise we retry later.
# Python
import hmac, hashlib, time
def ok(key, ts, body, signature):
expected = "sha256=" + hmac.new(key.encode(), f"{ts}.{body}".encode(), hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature) and abs(time.time() - int(ts)) < 300
Without a webhook, your system can fetch the status itself with GET /orders/{order_id}.
Errors are returned as {"error": "Explanation"}: 400 invalid data, 401 missing or invalid key, 403 the account is blocked, 404 not found, 409 the order is already booked, 423 the order system is paused, 429 too many requests (at most 120 per minute).
Send the header Accept-Language: en to get error messages in English (default is Danish).