Try everything here, with this token
Every call below has a button that really makes it. What comes back is from the server itself, not from an example in the text — including the errors.
rQIj1a8DGUng23lCAUKHKZpSzhsDv5l1zPvd9UCiqhF45ojk
This token is replaced as soon as you reload this page, and it cannot place orders. So do not build anything with it: turn on dropshipping in your own account for a token that stays.
Authentication
Every call carries your API token as a Bearer header. You will find that token in the dropship panel under API.
curl -H "Authorization: Bearer JOUW_TOKEN" https://api.l33d.be/api/dropship/status
- Amounts are in cents, VAT included.
- With a test token everything goes to the test environment: nothing is really ordered or paid. GET /status tells you where you are in environment.
- Errors come back as JSON with error: 401 invalid token, 404 not found or not yours, 422 invalid input, 429 too many requests, 503 maintenance (retry after Retry-After).
Endpoints
https://api.l33d.be/api/dropship
Account and catalogue
GET /status
Test your token: your account, your balance, whether invoice and credit are allowed, and live or test.
Command
Response
GET /products
All active products with prices in cents, the full quantity scale, the photo and the engraving area.
Command
Response
GET /addresses
Your address book of end customers.
Command
Response
Design
POST /position-sessions
Creates a session for a product and returns a white label link to the full editor.
Command
Response
GET /position-sessions/{token}
The result: status, the full layout and a preview.
Command
Response
POST /preview
A preview without ordering. Valid for an hour.
Command
Response
Orders
POST /orders
Place an order.
Command
Response
GET /orders
Your orders with status, end customer and tracking.
Command
Response
GET /orders/{number}
One order: lines, discounts, shipping, total, payment and can_cancel.
Command
Response
POST /orders/{number}/cancel
Cancel while can_cancel is true. Reason is optional.
{"reason":"Klant annuleerde"}
Credit
GET /credits
Your balance, whether you may use credit, and the last 100 transactions.
Command
Response
POST /credits/topup
Top up: returns a code and the url where payment happens.
Command
Response
GET /credits/topup/{code}
The state of that top-up and your new balance.
Command
Response
Address book and prices
POST /addresses
Add an address to your address book.
{"label":"Bakkerij","first_name":"Jan","last_name":"Peeters","street":"Kerkstraat","house_number":"12","postal_code":"3500","city":"Hasselt","country":"BE"}
PUT /addresses/{id}
Change an address, with the same fields.
DELETE /addresses/{id}
Delete an address.
PUT /products/{id}/price
Your own retail price for one product; null resets it to your markup.
{"price_cents":1299}
PUT /markup
Your markup in percent, for everything without its own price.
{"markup_percent":40}
Rather not build an editor yourself? That is the recommended route. See Positioning logos
Placing an order
The price in the response is what you pay us: quantity scale, your discount, surcharges, VAT and shipping to the end customer's address. What you charge your own customer is separate from that. You do not need to recalculate anything.
By default it comes off your credits and production starts immediately. If your balance is too low, or you ask for a payment link or an invoice, the order waits for payment.
Option A — through a confirmed positioning session. Supports everything: multiple texts, multiple logos, two sides.
curl -X POST https://api.l33d.be/api/dropship/orders \
-H "Authorization: Bearer JOUW_TOKEN" -H "Content-Type: application/json" \
-d '{
"reference": "WC-1042",
"payment": "credits",
"address": { "first_name": "Jan", "last_name": "Peeters",
"street": "Kerkstraat", "house_number": "12",
"postal_code": "3500", "city": "Hasselt", "country": "BE" },
"items": [
{ "quantity": 2, "position_session_token": "..." }
]
}'
Option B — text and one logo, straight in the call.
{
"items": [
{ "product_id": 23, "quantity": 2, "text": "Voor opa" },
{ "product_id": 23, "quantity": 1,
"logo_url": "https://jouwsite.be/logo.png",
"logo_position": { "cx": 0.5, "cy": 0.5, "w": 0.4, "angle": 90 } }
]
}
- payment: credits (default), link (the response contains pay_url) or invoice (if invoicing is enabled for you).
- The same reference within a day returns the existing order with already_known: true. Retrying after a timeout is safe.
- We fetch a logo_url ourselves, or send logo_base64. PNG, JPG or WebP, up to 5 MB. Without logo_position we centre it in the engraving area.
- If a product has colours (colors in GET products), send color_id. Without color_id we use the default colour.
- The response (201) contains order_number, total_cents, paid, insufficient_credits, credit_balance_cents, pay_url and track_url. Instead of a full address you may also send address_id from your address book.
One order: lines, totals and payment. Cancelling works while can_cancel is true; credits are not refunded automatically.
GET https://api.l33d.be/api/dropship/orders/{number}
POST https://api.l33d.be/api/dropship/orders/{number}/cancel
{ "reason": "Klant annuleerde" }
< { "ok": true, "status": "cancelled", "order": { ... } }
Topping up credit
Request a code, open the url in the browser, then poll the state. It is only paid when this call says so.
# 1. code aanvragen
POST https://api.l33d.be/api/dropship/credits/topup
{ "amount_cents": 5000 }
< { "ok": true, "code": "…", "url": "https://l33d.be/dropshipping/opwaarderen/…", "status": "open", "test": false }
# 2. url openen in de browser: daar wordt betaald
# 3. de stand opvragen tot betaald of mislukt
GET https://api.l33d.be/api/dropship/credits/topup/{code}
< { "ok": true, "status": "betaald", "balance_cents": 12500 }
status: open, betalen (paying), betaald (paid), mislukt (failed) or verlopen (expired). A code is valid for two hours. In the test environment the payment is simulated on that page.
Webhooks
Set a webhook URL in the dropship panel. We send a JSON message on every status change and as soon as tracking is available.
Verify the sender with the X-L33D-Signature header: a sha256 HMAC over the raw body, keyed with your API token.
$body = file_get_contents('php://input');
$sig = $_SERVER['HTTP_X_L33D_SIGNATURE'] ?? '';
if (!hash_equals(hash_hmac('sha256', $body, 'JOUW_TOKEN'), $sig)) {
http_response_code(401); exit;
}
$event = json_decode($body, true);
// X-L33D-Event / event: order.status_changed | order.tracking_added | test
// data: order_number, status, total_cents, tracking_code, tracking_url, end_customer