WhitepaperIssue token

Connect wallet

Connect wallet

Whitepaper
Issue token
API Docs
TEDR Merchant API

Accept escrow-protected payments

The TEDR Merchant API lets your shop create payment orders, hand the customer a checkout link, follow the order through its lifecycle and message the buyer — all over plain HTTPS and JSON. Funds are held in escrow until the buyer confirms delivery, so both sides are protected.

Base URLs

EnvironmentBase URL
Sandbox / testhttps://dev-openapi.tedr.com/api/v1
Productionhttps://openapi.tedr.com/api/v1

Every path in this reference is relative to the base URL and prefixed with /api/v1. All requests and responses are application/json; monetary amounts are always strings to avoid floating-point rounding.

Two order shapes.A multi-product order is the standard checkout — it carries a cart of one or more items and resolves the delivery address by redirect. A single-product order is a lighter, widget/SDK flow for a single item, where TEDR calls your confirmAmountUrl to let you recompute shipping and totals before payment.

What you can build

Single-product checkout

One item, one price, one link. Ideal for invoices, digital goods and “pay this” flows.

Multi-product cart

A full basket with per-item shipping, discounts and photos, rendered as a receipt.

Order chat

Send formatted messages to the buyer from your backend, attached to the order.

Fulfilment updates

Push processing, shipping and delivery states with tracking numbers and URLs.

Create an order
curl -X POST https://openapi.tedr.com/api/v1/multi-product-orders/init \
  -H "KeyID: $TEDR_KEY_ID" \
  -H "Timestamp: $(date +%s000)" \
  -H "Content-Type: application/json" \
  -d '{
    "orderId": "CART-88120",
    "subTotal": "129.00",
    "shippingCost": "9.00",
    "discount": "0.00",
    "totalCost": "138.00",
    "currency": "USTTETH",
    "successUrl": "https://shop.example.com/thanks",
    "failUrl": "https://shop.example.com/failed",
    "products": [
      { "name": "Mechanical keyboard", "price": "129.00", "quantity": 1, "photos": [], "attributes": [] }
    ]
  }'
201 CreatedJSON
{
  "id": "6650b1c2f3a1d40012ab77e1",
  "orderId": "CART-88120",
  "status": "order_created",
  "totalCost": "138.00",
  "currency": "USTTETH",
  "eosName": "tedrshop1234",
  "expiresAt": "2026-08-15T10:22:31.000Z",
  "link": "https://tedr.com/pay/6650b1c2f3a1d40012ab77e1"
}

Registration

How to obtain credentials and set the webhook that receives your order updates.

API credentials are issued from inside the TEDR app — there is no separate developer portal. To get yours:

  1. Download and open the TEDR app.
  2. Open the Service menu and go to the API SHOP section.
  3. Register your shop — fill in the shop name, shop URL and a default webhook URL (logo and description are optional).
  4. Once the shop is registered you receive your API Key and API Secret.

These map to the credentials you use on every request:

CredentialUsed as
KeyIDThe KeyID request header on every authenticated call.
SecretThe key used to compute the X-Signature header on Private requests.

Keep the secret on your server.Anyone holding it can act on behalf of your shop. Never ship it to a browser or mobile client.

The Webhook URL you register is your shop’s default callback. Any order can override it for its own lifetime by setting confirmStatusUrl at creation time — see Webhooks & redirects.

Where to find it in the app

TEDR app Service menu with the API SHOP section
Service menu → API SHOP
Register your shop form: name, URL, default webhook URL, logo, description
Register your shop & get API Key / Secret

Quickstart

Five steps from credentials to a paid order.

01

Get credentials

Register your shop to receive a KeyID and a Secret. The secret never leaves your server.

02

Create the order

POST /multi-product-orders/init with your orderId, the cart and successUrl/failUrl.

03

Redirect the buyer

Send them to the link in the response — that is the TEDR checkout page.

04

Receive webhooks

TEDR calls your confirmStatusUrl (or the registered webhook) on every status change.

05

Fulfil & update

POST /…/setStatus as you process and ship. Escrow releases when the buyer confirms receipt.

Idempotency.orderId is your identifier and must be unique per order in your system. TEDR returns its own id — store both: webhooks and every subsequent call use the TEDR id.

Authentication

Requests fall into three access levels. Most identify your shop with a key ID and a timestamp; state-changing and listing endpoints additionally require an HMAC signature.

Access levels

LevelRequired headersUsed by
OpenNone.All /enumerations endpoints.
PublicKeyID, TimestampOrder creation and single-order reads.
PrivateKeyID, Timestamp, Algorithm, X-SignatureListing, status changes and messages.

Headers

HeaderRequired onDescription
KeyIDPublic, PrivateYour application key ID.
TimestampPublic, PrivateCurrent time in milliseconds since the Unix epoch, as a string. Must be close to server time or the request is rejected with 401.
AlgorithmPrivateHMAC algorithm used for the signature: sha1, sha256, sha384 or sha512.
X-SignaturePrivateLowercase hex HMAC of the signed payload (below), keyed with your Secret.

What gets signed

The signed payload is the Timestamp header value, followed by the request path including the query string, followed — for requests that carry a body — by the JSON body:

  • GET (e.g. list): Timestamp + path, e.g. 1779330949362/api/v1/orders?status=order_payed.
  • POST (e.g. setStatus, messages): Timestamp + path + JSON.stringify(body).

The body counts.For signed POST requests the request body is part of the signature. Serialize it as compact JSON with no spaces ({"a":"b"}, not { "a": "b" }), keep the field order you send on the wire, and sign the exact same bytes you transmit. The resulting signature must be lowercase hex.

Which endpoints need a signature

LevelEndpoints
OpenAll /enumerations endpoints — no headers required.
PublicPOST /orders/init, GET /orders/{id}, POST /orders/{id}/setStatus, POST /multi-product-orders/init, GET /multi-product-orders/{id}KeyID + Timestamp only.
PrivateGET /orders, GET /multi-product-orders, POST /multi-product-orders/{id}/setStatus, POST /messages/{id} — all four headers.

Note the asymmetry.Per the backend integration guide, single-product POST /orders/{id}/setStatus is Public (no signature), while multi-product POST /multi-product-orders/{id}/setStatus is Private (signed).

Signing a request
# GET (no body): sign timestamp + path
REQ_PATH="/api/v1/orders?limit=20&status=order_payed"
TS=$(date +%s000)

SIG=$(printf "%s" "$TS$REQ_PATH" \
  | openssl dgst -sha512 -hmac "$TEDR_SECRET" -r \
  | cut -d' ' -f1)

curl "https://openapi.tedr.com$REQ_PATH" \
  -H "KeyID: $TEDR_KEY_ID" \
  -H "Timestamp: $TS" \
  -H "Algorithm: sha512" \
  -H "X-Signature: $SIG"

Sign the exact request.If you add, reorder or URL-encode query parameters — or re-serialize the body with different spacing — after computing the signature, verification fails with 401.

Test mode

A shortcut for wiring up the integration before your signing code is ready.

On the sandbox host you may send the literal string API_INTEGRATE as the X-Signature header instead of a real HMAC. This lets you exercise every Private endpoint from Postman or the playground while your backend signing is still in progress.

Never use API_INTEGRATE in production.Switch to real, server-side signatures and re-test every Private endpoint before going live.

The sandbox playground can generate signatures for you and lets you point webhooks at a webhook.site URL to inspect the callbacks TEDR sends.

Sandbox-only shortcutcURL
curl "https://openapi.tedr.com/api/v1/orders?limit=5" \
  -H "KeyID: $TEDR_KEY_ID" \
  -H "Timestamp: $(date +%s000)" \
  -H "Algorithm: sha512" \
  -H "X-Signature: API_INTEGRATE"

Order lifecycle

How an order moves from creation to escrow release — and who moves it.

SHOP

order_created

You call /init. TEDR returns a checkout link and an expiresAt.

BUYER

address_confirmed

Buyer opens the link and confirms the delivery address, if the flow requires one.

BUYER

payment_processing

Payment submitted; TEDR waits for confirmation from the payment provider.

TEDR

order_confirmed

Funds are held in escrow until delivery is confirmed. This is your green light to ship.

SHOP

order_processing

You acknowledge the order via setStatus and start preparing it.

SHOP

order_delivering

setStatus — optionally with tracking info (single-product orders carry trackingNumber/trackingUrl).

SHOP

order_delivered

You mark the parcel as delivered and notify the buyer.

BUYER

order_received

Buyer confirms receipt → escrow releases the payment to your shop.

Direct payment

order_payed means the buyer paid without escrow. Such orders end at order_delivered — there is no buyer confirmation step.

Disputes

The buyer can open a dispute (order_disputed). If it resolves in their favour the goods come back and the order lands in order_returned.

Expiry & failure

Unpaid orders reach order_expired after expiresAt. A rejected payment yields payment_failed.

You can only set three statuses.setStatus accepts order_processing, order_delivering and order_delivered. Everything else is driven by the buyer, the payment provider or TEDR itself.

Multi-product start state.If you pass customerEmail at creation, a multi-product order starts in address_confirmed. Without it, the order starts in order_created and moves to address_confirmed once the buyer fills/saves the address during checkout.

Order statuses

The complete set, also available at runtime from GET /enumerations/orderStatuses.

order_createdOrder was created. Set by Shop.
order_expiredOrder was expired. Set by TEDR.
address_confirmedUser confirmed delivery address. Set by Buyer.
order_confirmedPayment held in escrow until delivery. Set by TEDR.
order_payedUser paid for the order directly without escrow; the order ends in order_delivered. Set by TEDR.
order_processingShop has sent a notification about the start of order processing. Set by Shop.
order_deliveringShop has sent a notification about the start of order delivery. Set by Shop.
order_deliveredShop sent notification about order delivery. Set by Shop.
order_receivedPayment released to the shop when the user confirmed receiving delivery. Set by Buyer.
order_disputedUser opened a dispute. Set by Buyer.
order_returnedAs a result of the dispute resolution, the goods were returned to the shop. Set by TEDR.
payment_processingUser has paid the order, waiting for “success” from payment providers. Set by TEDR.
payment_failedPayment processing returned a failed status. Set by TEDR.
order_paid_requires_address_confirmUser has paid the order; the order is waiting for address confirmation. Set by TEDR.

Webhooks & redirects

TEDR notifies your backend by calling URLs you control. A default webhook is set at registration; each order may add or override callback URLs at creation time.

Callback & redirect URLs

FieldWhen TEDR calls it
webhookUrlregistrationYour shop-wide default, set in TEDR App settings at registration. Receives every order-status change unless an order overrides it.
confirmStatusUrlPer-order server-to-server callback on every status transition. Overrides the registered webhookUrl for that order. Use it as your source of truth for “paid”, “received”, “disputed”.
confirmAmountUrlsingle-productServer-to-server, before payment: TEDR asks your backend to confirm the final amounts (items, shipping, total). Single-product flow only — see below.
successUrlWhere the buyer’s browser lands after a successful payment.
failUrlmulti-productBrowser redirect after a failed payment. Required on multi-product orders.
redirectUrlsingle-productGeneric return URL for the buyer. Single-product orders only.
backToStoreUrlmulti-product“Back to store” link shown on the checkout page. Multi-product orders only.

Status callback

When an order’s status changes, TEDR sends a POST to confirmStatusUrl (or the registered webhookUrl). The body is the full OrderDto or MultiProductOrderDto. Your endpoint must return a 2xx (200 or 201). TEDR retries a failed delivery up to 5 times per order.

  • Respond 2xx quickly; do the heavy work asynchronously.
  • Treat callbacks as hints — re-read the order with GET before shipping anything.
  • Make handlers idempotent: the same status may arrive more than once.
  • Use unguessable callback paths (include a nonce) and serve them over HTTPS.

Confirm delivery address / amount single-product

In the single-product flow, when the buyer scans the QR and fills in the address, TEDR sends a POST to your confirmAmountUrl so you can recompute shipping and totals before payment.

TEDR sends:

FieldTypeDescription
orderIdstringThe order’s id.
addressAddressDtoDelivery address (country is ISO 3166 alpha-2/alpha-3; email optional).
signaturestringmd5 hex hash of orderId + signKey. Empty string when no signKey is configured.

Your backend replies:

FieldTypeDescription
orderIdreqstringMust equal the id from the request.
amountTotaloptstringTotal amount of order. Default: item’s amount.
amountItemsoptstringAmount of items in the order.
amountShippingoptstringAmount of shipping. Default: 0.
expiresAtoptstringISO 8601; must be later than now. If set, extends the order’s expiry.

Query parameters are yours.Any query string you put on a callback URL is preserved and echoed back, which makes it a convenient place for your own order reference.

Status callback handler
// confirmStatusUrl handler — body is the full order DTO
app.post("/tedr/status", async (req, res) => {
  res.sendStatus(200); // acknowledge with 2xx immediately

  const order = req.body;          // OrderDto | MultiProductOrderDto
  switch (order.status) {
    case "order_confirmed":
      await startFulfilment(order.orderId);
      break;
    case "order_received":
      await markPaidOut(order.orderId);
      break;
    case "order_disputed":
      await alertSupport(order.orderId);
      break;
  }
});
confirmAmountUrl replyJSON
{
  "orderId": "SHOP-1042",
  "amountItems": "129.00",
  "amountShipping": "9.00",
  "amountTotal": "138.00",
  "expiresAt": "2026-08-15T11:00:00.000Z"
}

Display currency

Charge in the settlement asset, show the price in the buyer’s money.

currency is the asset the order is actually settled in — the supported values come from GET /enumerations/currencies. Everything prefixed with display is presentation only: you supply the symbol, the rate you used and the already-converted figures, and TEDR renders them next to the settlement amounts.

FieldPurpose
displayCurrencyAny symbol you want shown, e.g. USD, EUR, RUB.
displayRateThe rate you used at order-creation time, e.g. "1.25".
displayAmount · displaySubTotalConverted item amount / cart subtotal.
displayAmountShipping · displayShippingCostConverted shipping cost.
displayDiscountConverted discount.
displayAmountTotal · displayTotalCostConverted grand total.

TEDR does not convert for you.The display figures are stored and rendered exactly as you send them — the rate and the arithmetic are your responsibility.

Order with display currencyJSON
{
  "orderId": "CART-88120",
  "subTotal": "129.00",
  "shippingCost": "9.00",
  "discount": "0.00",
  "totalCost": "138.00",
  "currency": "USTTETH",
  "successUrl": "https://shop.example.com/thanks",
  "failUrl": "https://shop.example.com/failed",

  "displayCurrency": "EUR",
  "displayRate": "0.92",
  "displaySubTotal": "118.68",
  "displayShippingCost": "8.28",
  "displayDiscount": "0.00",
  "displayTotalCost": "126.96",
  "products": [ /* … */ ]
}

Errors

Standard HTTP status codes. Validation failures return a list of messages; auth failures return a single message.

CodeMeaningWhat to check
200 / 201Success.
400Bad request — validation failed. message is a string array.Missing required fields, amounts not sent as strings, bad ISO country code, malformed expiresAt.
401Unauthorized.Missing required headers, unknown KeyID, unacceptable Timestamp (clock skew), or an invalid X-Signature / signed payload.
500Server error.Retry with backoff; contact support if it persists.

Keep your server clock in sync with NTP — a drifting Timestamp is the most common cause of unexpected 401s. The second most common is a signature computed over a different path or body than the one actually sent.

401 UnauthorizedJSON
{
  "statusCode": 401,
  "message": "Unauthorized"
}
400 Bad requestJSON
{
  "statusCode": 400,
  "message": [
    "currency must be one of the following values: USTTETH",
    "totalCost must be a string"
  ]
}
Orders

Initialize order

Creates a single-product order and returns a checkout link for the buyer. Meant for the widget/SDK flow.

POST/api/v1/orders/initPublic

Body — CreateOrderDto

FieldTypeDescription
orderIdreqstringYour own order identifier. Must be unique in your system.
namereqstringItem name shown to the buyer, e.g. "Best ever order".
amountreqstringItem amount, as a decimal string.
currencyreqenumSettlement asset — see currencies. One of: USTTETH.
confirmAmountUrlreqstringServer-to-server URL TEDR calls to confirm item / shipping / total amounts before payment.
totalAmountoptstringGrand total including shipping, minus discount.
discountoptstringDiscount applied to the item.
expiresAtoptdate-timeISO 8601 string; use UTC. After this moment the order becomes order_expired.
attributesoptOrderAttribute[]Name/value pairs displayed as is on the checkout page.
photosoptstring[]Image URLs for the item.
addressoptInputAddressDtoPre-filled delivery address. If provided, the order starts in address_confirmed.
canResetAddressoptbooleanWhether the buyer may change the pre-filled address.
redirectUrl · successUrl · confirmStatusUrloptstringSee Webhooks & redirects. confirmStatusUrl overrides the registered webhook.
display*optstringPresentation-only amounts — see Display currency.
cashbackInfooptCashbackInfoDtoCashback percent / amount / currency shown to the buyer.

Response

201OrderDto. Persist id (TEDR's identifier) and send the buyer to link.

Request
curl -X POST https://openapi.tedr.com/api/v1/orders/init \
  -H "KeyID: $TEDR_KEY_ID" \
  -H "Timestamp: $(date +%s000)" \
  -H "Content-Type: application/json" \
  -d '{
    "orderId": "SHOP-1042",
    "name": "Mechanical keyboard",
    "amount": "129.00",
    "totalAmount": "138.00",
    "currency": "USTTETH",
    "confirmAmountUrl": "https://shop.example.com/tedr/amount?ref=1042",
    "confirmStatusUrl": "https://shop.example.com/tedr/status?ref=1042",
    "photos": ["https://cdn.example.com/kb.jpg"],
    "attributes": [{ "name": "Switch", "value": "Brown" }]
  }'
201 CreatedJSON
{
  "id": "507f1f77bcf86cd799439011",
  "orderId": "SHOP-1042",
  "name": "Mechanical keyboard",
  "status": "order_created",
  "amount": "129.00",
  "totalAmount": "138.00",
  "eosName": "tedrshop1234",
  "currency": "USTTETH",
  "expiresAt": "2026-08-15T10:22:31.000Z",
  "confirmAmountUrl": "https://shop.example.com/tedr/amount?ref=1042",
  "link": "https://tedr.com/pay/507f1f77bcf86cd799439011"
}
Orders

Get order

Reads the current state of a single-product order. Use this after every status webhook.

GET/api/v1/orders/{id}Public

Path parameters

NameTypeDescription
idreqstringTEDR order ID, e.g. 507f1f77bcf86cd799439011 — not your orderId.

Response

200OrderDto. Requests for an order that belongs to another shop are rejected with 401.

Request
curl https://openapi.tedr.com/api/v1/orders/507f1f77bcf86cd799439011 \
  -H "KeyID: $TEDR_KEY_ID" \
  -H "Timestamp: $(date +%s000)"
Orders

List orders

Paginated list of your shop's single-product orders, newest first by default.

GET/api/v1/ordersPrivate

Query parameters

NameTypeDescription
offsetoptnumberRows to skip. Minimum 0, default 0.
limitoptnumberPage size, 1100. Default 20.
sortoptnumber-1 newest first (default) or 1 oldest first.
statusoptenumFilter by one of the order statuses.

Sign the full path.The query string is part of the signed payload: sign /api/v1/orders?limit=20&status=order_payed, not /api/v1/orders.

Response

200OrdersDto: a pagination block plus an array of OrderDto.

Request
REQ_PATH="/api/v1/orders?limit=20&offset=0&sort=-1&status=order_confirmed"
TS=$(date +%s000)
SIG=$(printf "%s" "$TS$REQ_PATH" \
  | openssl dgst -sha512 -hmac "$TEDR_SECRET" -r | cut -d' ' -f1)

curl "https://openapi.tedr.com$REQ_PATH" \
  -H "KeyID: $TEDR_KEY_ID" \
  -H "Timestamp: $TS" \
  -H "Algorithm: sha512" \
  -H "X-Signature: $SIG"
200 OKJSON
{
  "pagination": { "offset": 0, "count": 20, "total": 137, "prev": false, "next": true },
  "orders": [
    {
      "id": "507f1f77bcf86cd799439011",
      "orderId": "SHOP-1042",
      "status": "order_confirmed",
      "amount": "129.00",
      "totalAmount": "138.00",
      "currency": "USTTETH",
      "link": "https://tedr.com/pay/507f1f77bcf86cd799439011"
    }
  ]
}
Orders

Set order status

Moves a paid single-product order through fulfilment and notifies the buyer.

POST/api/v1/orders/{id}/setStatusPublic

Public on single-product orders.Per the backend integration guide this endpoint needs only KeyID + Timestamp — no signature. (The multi-product equivalent is Private.)

Body — InputSetOrderStatusBody

FieldTypeDescription
statusreqenumOne of order_processing, order_delivering, order_delivered.
trackingNumberreqstringCarrier tracking number.
trackingUrlreqstringURL where the buyer can track the parcel.
messagereqCreateMessageDtoMessage delivered to the buyer alongside the status change.
attributesoptOrderAttribute[]Extra name/value details shown with the update.
cashbackInfooptCashbackInfoDtoCashback granted with this transition.

Order of operations.Wait for order_confirmed (escrow held) or order_payed before you start fulfilment. Setting a status on an unpaid order returns 400.

Response

200BaseResponseDto.

Request
# Public: KeyID + Timestamp, no signature
curl -X POST https://openapi.tedr.com/api/v1/orders/507f1f77bcf86cd799439011/setStatus \
  -H "KeyID: $TEDR_KEY_ID" \
  -H "Timestamp: $(date +%s000)" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "order_delivering",
    "trackingNumber": "JD0002123456789",
    "trackingUrl": "https://dhl.com/track/JD0002123456789",
    "message": { "message": "Your parcel is on its way!" }
  }'
200 OKJSON
{
  "statusCode": 200,
  "message": "OK"
}
Multi-product orders

Initialize multi-product order

Creates a cart-style order with a product list, per-item shipping and totals. Carries one or more items.

POST/api/v1/multi-product-orders/initPublic

Body — CreateMultiProductOrderDto

FieldTypeDescription
orderIdreqstringYour order identifier.
productsreqOrderProductDto[]Line items: name, unit price, quantity, photos, attributes, optional per-item shipping.
subTotalreqstringSum of the products.
shippingCostreqstringTotal shipping.
discountreqstringTotal discount.
totalCostreqstringGrand total the buyer pays.
currencyreqenumSettlement asset. One of: USTTETH.
successUrlreqstringBrowser redirect after successful payment.
failUrlreqstringBrowser redirect after failed payment.
shippingoptShippingDtoOrder-level carrier and cost.
confirmStatusUrloptstringPer-order status callback; overrides the registered webhook.
backToStoreUrloptstring“Back to store” link on the checkout page.
customerEmailoptstringBuyer email for status notifications. Affects the initial status — see note.
display* · cashbackInfooptSee Display currency and CashbackInfoDto.

Initial status depends on customerEmail.With customerEmail the order is created in address_confirmed. Without it, it is created in order_created and becomes address_confirmed after the buyer fills/saves the address during checkout.

Totals are yours to compute.Send subTotal + shippingCost − discount = totalCost; TEDR renders the numbers you provide.

Response

201MultiProductOrderDto.

Request
curl -X POST https://openapi.tedr.com/api/v1/multi-product-orders/init \
  -H "KeyID: $TEDR_KEY_ID" \
  -H "Timestamp: $(date +%s000)" \
  -H "Content-Type: application/json" \
  -d '{
    "orderId": "CART-88120",
    "subTotal": "2988.00",
    "shippingCost": "20.00",
    "discount": "10.00",
    "totalCost": "2998.00",
    "currency": "USTTETH",
    "successUrl": "https://shop.example.com/thanks",
    "failUrl": "https://shop.example.com/failed",
    "confirmStatusUrl": "https://shop.example.com/tedr/status?ref=88120",
    "customerEmail": "buyer@example.com",
    "shipping": { "name": "DHL", "shippingCost": "20.00" },
    "products": [
      { "name": "iPhone 14 Plus", "price": "1469.00", "quantity": 2,
        "photos": ["https://cdn.example.com/iphone.jpg"],
        "attributes": [{ "name": "Colour", "value": "Midnight" }] },
      { "name": "USB-C cable", "price": "25.00", "quantity": 2, "photos": [], "attributes": [] }
    ]
  }'
201 CreatedJSON
{
  "id": "6650b1c2f3a1d40012ab77e1",
  "orderId": "CART-88120",
  "status": "address_confirmed",
  "subTotal": "2988.00",
  "shippingCost": "20.00",
  "discount": "10.00",
  "totalCost": "2998.00",
  "currency": "USTTETH",
  "eosName": "tedrshop1234",
  "expiresAt": "2026-08-15T10:22:31.000Z",
  "link": "https://tedr.com/pay/6650b1c2f3a1d40012ab77e1",
  "successUrl": "https://shop.example.com/thanks",
  "failUrl": "https://shop.example.com/failed",
  "customerEmail": "buyer@example.com",
  "products": [ /* … */ ]
}
Multi-product orders

Get multi-product order

Reads a cart order, including the full product list.

GET/api/v1/multi-product-orders/{id}Public
NameInDescription
idreqpathTEDR multi-product order ID.

200MultiProductOrderDto.

Separate ID space.Multi-product orders are not returned by GET /orders/{id} — use this endpoint and GET /multi-product-orders for them.

Request
curl https://openapi.tedr.com/api/v1/multi-product-orders/6650b1c2f3a1d40012ab77e1 \
  -H "KeyID: $TEDR_KEY_ID" \
  -H "Timestamp: $(date +%s000)"
Multi-product orders

List multi-product orders

Same pagination and filtering as List orders.

GET/api/v1/multi-product-ordersPrivate
NameTypeDescription
offsetoptnumberDefault 0.
limitoptnumber1100, default 20.
sortoptnumber-1 or 1, default -1.
statusoptenumAny order status.

200MultiProductOrdersDto.

Request
REQ_PATH="/api/v1/multi-product-orders?limit=50&status=order_payed"
TS=$(date +%s000)
SIG=$(printf "%s" "$TS$REQ_PATH" \
  | openssl dgst -sha256 -hmac "$TEDR_SECRET" -r | cut -d' ' -f1)

curl "https://openapi.tedr.com$REQ_PATH" \
  -H "KeyID: $TEDR_KEY_ID" \
  -H "Timestamp: $TS" \
  -H "Algorithm: sha256" \
  -H "X-Signature: $SIG"
Multi-product orders

Set multi-product order status

Fulfilment updates for cart orders. No tracking fields — status and optional cashback only.

POST/api/v1/multi-product-orders/{id}/setStatusPrivate

Body — InputSetMultiProductOrderStatusBody

FieldTypeDescription
statusreqenumorder_processing, order_delivering or order_delivered.
cashbackInfooptCashbackInfoDtoCashback granted with this transition.

200BaseResponseDto.

Sign Timestamp + path + JSON.stringify(body). To message the buyer about a cart order, call POST /messages/{id}?multi_product=true separately.

Request
ID="6650b1c2f3a1d40012ab77e1"
REQ_PATH="/api/v1/multi-product-orders/$ID/setStatus"
BODY='{"status":"order_processing"}'          # compact, no spaces
TS=$(date +%s000)
SIG=$(printf "%s" "$TS$REQ_PATH$BODY" \
  | openssl dgst -sha512 -hmac "$TEDR_SECRET" -r | cut -d' ' -f1)

curl -X POST "https://openapi.tedr.com$REQ_PATH" \
  -H "KeyID: $TEDR_KEY_ID" \
  -H "Timestamp: $TS" \
  -H "Algorithm: sha512" \
  -H "X-Signature: $SIG" \
  -H "Content-Type: application/json" \
  -d "$BODY"
Messages

Send message to order

Posts a message into the order chat the buyer sees in the TEDR app.

POST/api/v1/messages/{id}Private

Parameters

NameInDescription
idreqpathTEDR order ID.
multi_productoptquerySet to true when the ID refers to a multi-product order.

Body — CreateMessageDto

FieldTypeDescription
messagereqstringPlain text, e.g. "Hello, dear customer!".
entitiesoptMessageEntityDto[]Rich-text ranges: links, bold, italic, underline, strike, hashtag, email, phone.

The order must be live.Messages are rejected for orders still in order_created or already order_expired, and for orders that belong to another shop.

Entity offsets

offset is a 0-based index into the message text (0–4090) and length is 1–4096. For text_url entities also supply url.

200BaseResponseDto.

Request
ID="507f1f77bcf86cd799439011"
REQ_PATH="/api/v1/messages/$ID"
BODY='{"message":"Your order shipped. Track it here.","entities":[{"type":"bold","offset":0,"length":10}]}'
TS=$(date +%s000)
SIG=$(printf "%s" "$TS$REQ_PATH$BODY" \
  | openssl dgst -sha512 -hmac "$TEDR_SECRET" -r | cut -d' ' -f1)

curl -X POST "https://openapi.tedr.com$REQ_PATH" \
  -H "KeyID: $TEDR_KEY_ID" \
  -H "Timestamp: $TS" \
  -H "Algorithm: sha512" \
  -H "X-Signature: $SIG" \
  -H "Content-Type: application/json" \
  -d "$BODY"
200 OKJSON
{
  "statusCode": 200,
  "message": "OK"
}
Enumerations

Get enabled schema names

Lists the JSON schema names you can pass to GET /enumerations/{schema}.

GET/api/v1/enumerationsOpen

No parameters and no authentication headers. Useful as a health check and to discover what the API considers valid before you hard-code anything.

200 → string[]

Request & responsecURL
curl https://openapi.tedr.com/api/v1/enumerations

# ["currencies", "orderStatuses", "hmac"]
Enumerations

Get available currencies

Supported settlement assets with their precision and minimum amount.

GET/api/v1/enumerations/currenciesOpen

200CurrencyDto[]. Use decimals to format amounts and minimalAmount to validate carts before you call /init.

Read this at runtime.The set of supported assets changes over time — cache the response for minutes, not months, rather than hard-coding currency codes.

200 OKJSON
[
  {
    "currency": "USTTETH",
    "decimals": 2,
    "minimalAmount": "0.01"
  }
]
Enumerations

Get order statuses

Machine-readable version of the status table.

GET/api/v1/enumerations/orderStatusesOpen

200OrderStatusDto[] — each entry pairs a status code with its human-readable description.

200 OKJSON
[
  { "status": "order_created",   "description": "Order was created" },
  { "status": "order_expired",   "description": "Order was expired" },
  { "status": "order_confirmed", "description": "Payment held until delivery" }
]
Enumerations

Get HMAC algorithms

The signature algorithms accepted in the Algorithm header.

GET/api/v1/enumerations/hmacOpen

200 → string[]. Prefer sha512; sha1 exists for legacy integrations only.

200 OKJSON
["sha1", "sha256", "sha384", "sha512"]
Enumerations

Get JSON schema by name

Returns the raw JSON schema for one enumeration.

GET/api/v1/enumerations/{schema}Open
NameInDescription
schemareqpathA name from GET /enumerations, e.g. currencies, orderStatuses, hmac.

200 → object — a JSON schema document you can feed straight into a validator such as Ajv. Use these for internal validation of your payloads.

RequestcURL
curl https://openapi.tedr.com/api/v1/enumerations/currencies
Reference

Data models

Every object the API accepts or returns. Fields marked req are required; all amounts are decimal strings.

FieldTypeDescription
orderIdreqstringYour own order identifier. Must be unique in your system.
namereqstringOrder item's name. e.g. "Best ever order".
amountreqstringItem amount as a decimal string. e.g. "1".
currencyreqenumSettlement asset. One of: USTTETH.
confirmAmountUrlreqstringServer-to-server URL TEDR calls to confirm the amounts.
discountoptstringDiscount applied to the item. e.g. "0.01".
totalAmountoptstringGrand total including shipping, minus discount. e.g. "1.01".
attributesoptOrderAttribute[]Attributes will be displayed AS IS.
photosoptstring[]Image URLs for the item.
redirectUrl · successUrl · confirmStatusUrloptstringRedirect / callback URLs — see Webhooks.
displayCurrency · displayRate · displayAmount · displayAmountShipping · displayDiscount · displayAmountTotaloptstringPresentation-only — see Display currency.
cashbackInfooptCashbackInfoDtoCashback details.
expiresAtoptdate-timeISO 8601 (UTC). e.g. "2026-07-16T18:50:53.074Z".
addressoptInputAddressDtoPre-filled delivery address.
canResetAddressoptbooleanWhether the buyer may replace a pre-filled address.

OrderDto

A single-product order, as returned by the order endpoints and the status webhook.

FieldTypeDescription
idreqstringTEDR order ID. Use this in every subsequent call.
orderIdreqstringThe identifier you supplied at creation.
namereqstringOrder item's name.
statusreqenumCurrent status — see Order statuses.
amountreqstringItem amount.
discountoptstringDiscount applied.
shippingAmountoptstringShipping cost confirmed via confirmAmountUrl.
totalAmountreqstringGrand total the buyer pays.
eosNamereqstringBlockchain account name of your shop.
currencyreqenumSettlement asset. One of: USTTETH.
expiresAtreqdate-timeMoment the order stops accepting payment.
confirmAmountUrlreqstringAmount-confirmation callback recorded on the order.
linkreqstringTEDR checkout URL — send the buyer here.
addressoptAddressDtoDelivery address confirmed by the buyer.
newAddressFlowStrategyoptbooleanWhether the order uses the newer address-confirmation flow.
escrowHoldoptbooleantrue while funds are held in escrow.
transactionIdoptstringPayment transaction reference, once paid.
attributesoptOrderAttribute[]Displayed AS IS.
photosoptstring[]Image URLs for the item.
customeroptstringOpaque buyer identifier.
redirectUrl · successUrl · confirmStatusUrloptstringURLs recorded on the order.
canResetAddressoptbooleanWhether the buyer may change the address.
display* · cashbackInfooptPresentation amounts and cashback, echoed back.

OrdersDto

Paginated envelope returned by GET /orders.

FieldTypeDescription
paginationreqHttpPaginationDtoOffset, page size and totals.
ordersreqOrderDto[]The page of orders.
FieldTypeDescription
orderIdreqstringYour own order identifier.
subTotalreqstringSubtotal for the products. e.g. "2988.00".
shippingCostreqstringTotal shipping cost. e.g. "20.00".
discountreqstringTotal discount. e.g. "10.00".
totalCostreqstringGrand total payable. e.g. "2998.00".
currencyreqenumSettlement asset. One of: USTTETH.
productsreqOrderProductDto[]List of products.
successUrlreqstringBrowser redirect after a successful payment.
failUrlreqstringBrowser redirect after a failed payment.
shippingoptShippingDtoOrder-level delivery company.
confirmStatusUrloptstringPer-order status callback; overrides the registered webhook.
customerEmailoptstringBuyer email; affects the initial status (see Initialize).
displayCurrency · displayRate · displaySubTotal · displayShippingCost · displayDiscount · displayTotalCostoptstringPresentation-only — see Display currency.
cashbackInfooptCashbackInfoDtoCashback details.
backToStoreUrloptstring“Back to store” link shown on the checkout page.

MultiProductOrderDto

A cart order with its product list. Returned by the multi-product endpoints and the status webhook.

FieldTypeDescription
idreqstringTEDR order ID.
orderIdreqstringThe identifier you supplied at creation.
subTotal · shippingCost · discount · totalCostreqstringThe order totals you supplied.
currencyreqenumSettlement asset. One of: USTTETH.
productsreqOrderProductDto[]List of products.
shippingoptShippingDtoDelivery company.
successUrl · failUrlreqstringRedirect URLs recorded on the order.
confirmStatusUrl · customerEmailoptstringStatus callback and buyer email.
eosNamereqstringBlockchain account name of your shop.
statusreqenumCurrent status — see Order statuses.
expiresAtreqdate-timeMoment the order stops accepting payment.
linkreqstringTEDR checkout URL.
transactionId · customeroptstringPayment reference and opaque buyer identifier.
display* · cashbackInfo · backToStoreUrloptPresentation amounts, cashback and the back-to-store link.
fiatTokenizationRequiredoptstringSet when the payment requires fiat tokenisation.

MultiProductOrdersDto

Paginated envelope returned by GET /multi-product-orders.

FieldTypeDescription
paginationreqHttpPaginationDtoOffset, page size and totals.
ordersreqMultiProductOrderDto[]The page of multi-product orders.

OrderProductDto

One line item inside a multi-product order.

FieldTypeDescription
namereqstringProduct name.
pricereqstringPrice per unit.
quantityreqnumberPositive integer quantity.
photosreqstring[]Image URLs for this product.
attributesreqOrderAttribute[]List of product attributes.
shippingoptShippingDtoPer-product carrier and cost.
displayPriceoptstringUnit price in the buyer's display currency.

ShippingDto

Carrier and shipping cost, at order or product level.

FieldTypeDescription
namereqstringDelivery company name. e.g. "DHL".
shippingCostreqstringShipping price. e.g. "20.00".
displayShippingCostoptstringShipping price in a display currency.

InputAddressDto

Delivery address you may pre-fill when creating an order.

FieldTypeDescription
countryreqstringISO 3166-1 alpha-2 or alpha-3 country code. e.g. "RU".
idoptstringExisting address ID, when reusing a stored address.
address · city · region · postaloptstringStreet, city, region/state and postal code.
fullName · phone · email · commentoptstringRecipient name, phone, email and courier note.
geooptGeoPointOptional coordinates.

AddressDto

Delivery address as stored by TEDR, including its id.

FieldTypeDescription
idreqstringTEDR address ID.
countryreqstringISO 3166-1 alpha-2 or alpha-3 country code.
address · city · region · postaloptstringStreet, city, region/state and postal code.
fullName · phone · email · commentoptstringRecipient name, phone, email and courier note.
geooptGeoPointOptional coordinates.

GeoPoint

Latitude / longitude pair attached to an address.

FieldTypeDescription
latreqnumberLatitude. e.g. 56.477956.
lonreqnumberLongitude. e.g. 84.965033.

OrderAttribute

Free-form name/value detail rendered as is on the checkout page.

FieldTypeDescription
namereqstringAttribute name.
valuereqstringAttribute value.
entitiesoptMessageEntityDto[]Rich-text ranges applied to value.

MessageEntityDto

Rich-text range inside a message — links, bold, italic and friends.

FieldTypeDescription
typereqenumOne of text_url, hashtag, email, bold, italic, phone, underline, strike.
offsetreqnumberInteger in range 0..4090 inclusive.
lengthreqnumberInteger in range 1..4096 inclusive.
urloptstringTarget URL, required for text_url entities (length 1..4096).

CreateMessageDto

Message payload used by POST /messages/{id} and inside single-product setStatus.

FieldTypeDescription
messagereqstringMessage text shown to the buyer.
entitiesoptMessageEntityDto[]Rich-text ranges inside message.
FieldTypeDescription
statusreqenumOne of order_processing, order_delivering, order_delivered.
trackingNumberreqstringOrder's tracking number.
trackingUrlreqstringOrder's tracking number URL.
messagereqCreateMessageDtoMessage to the buyer.
attributesoptOrderAttribute[]Extra details displayed with the update.
cashbackInfooptCashbackInfoDtoCashback details.
FieldTypeDescription
statusreqenumOne of order_processing, order_delivering, order_delivered.
cashbackInfooptCashbackInfoDtoCashback details.

CashbackInfoDto

Cashback shown to the buyer for an order.

FieldTypeDescription
percentoptnumberCashback rate, e.g. 0.1 for 10%.
amountoptstringCashback amount. e.g. "10".
currencyoptstringCashback currency. Defaults to the order currency.

CurrencyDto

A supported settlement asset.

FieldTypeDescription
currencyreqenumCurrency code. One of: USTTETH.
decimalsreqnumberNumber of decimal places. e.g. 2.
minimalAmountreqstringSmallest amount accepted for this currency. e.g. "0.01".

OrderStatusDto

A status code paired with its human-readable description.

FieldTypeDescription
statusreqenumStatus code — see Order statuses.
descriptionreqstringHuman-readable description of the status.

HttpPaginationDto

Pagination block returned with every list endpoint.

FieldTypeDescription
offsetreqnumberOffset of the first row in this page.
countreqnumberNumber of rows in this page.
totalreqnumberTotal rows matching the filter.
prevreqbooleanWhether a previous page exists.
nextreqbooleanWhether a next page exists.

BaseResponseDto

Generic acknowledgement body returned by setStatus and messages.

FieldTypeDescription
statusCodereqnumberHTTP status code, echoed in the body. Defaults to 200.
messagereqstringHuman-readable result, e.g. OK. For 400 errors this is a string array instead.