Connect your systems.

Your TMS, ERP or EDI flow speaks to Tendered through one shared contract. Map your columns once; every door lands the same way. Your engineer's AI agent can build the whole connection from the skill file.

The shapes

ShapeIn plain words
PartyA company on a movement: the shipper you ran it for (customer), the forwarder above you when the row is a subcontract (forwarderCustomer), the subcontractor who ran it (carrier).
LaneExact loading and unloading — city and postcode, a country on both ends ("Lille 59000, FR → Essen 45127, DE") — with its equipment.
RateA stated rate is always scoped: it sits on a lane (exact loading and unloading, per trip) or on a corridor (zone to zone at the two-digit postcode level, a country on both ends, per km). The basis follows the precision. A shipment row carries its own lane, so the scope travels with the number.
ShipmentOne executed movement: the lane, the day it ran, what was billed (shipperRateEur) and what was paid (carrierCostEur) as two separate fields, references, the truck, the driver, and the planned and actual hours of loading and unloading.

Only what is known travels — absent fields stay empty, and every held-back or unreadable row comes back counted, by position, with its reason in words.

The doors

API pullTendered reads your endpoint on the connection's schedule — an https address answering rows as JSON, the key stored encrypted.
Webhook pushYour system POSTs batches to /api/integrations/hook/{token} on your clock — up to 5 MB and 5000 rows per delivery, 60 deliveries per hour.
Dry runBeside the webhook: /api/integrations/hook/{token}/validate reads a sample through the exact same reading and stores nothing — the answer says what parsed, what would land, and what would be skipped and why.
Files and e-mailExports land as CSV through upload or the workspace's intake address. EDI arrives as files — an EDIFACT flow lands through the same door.

Each connection's door is its own unguessable token, minted inside Tendered, shown once and stored hashed. An unknown token answers 404 with nothing else said.

The dry-run loop

Post a sample, read what parsed, fix, repeat — then point the real sends at the webhook door. A sample batch (every company fictional, each rate on its own named lane):

[
  {
    "origin": "Lille 59000, FR",
    "destination": "Essen 45127, DE",
    "equipment": "Tautliner",
    "date": "2026-07-14",
    "shipperRateEur": 980,
    "customer": "Nordwind Spedition",
    "km": 320,
    "sourceReference": "SHP-104233"
  },
  {
    "origin": "Gent 9000, BE",
    "destination": "Lyon 69007, FR",
    "equipment": "Frigo",
    "date": "2026-07-15",
    "carrierCostEur": 1140,
    "customer": "Bellamare Foods",
    "km": 780,
    "sourceReference": "SHP-104234"
  }
]

The dry run's answer — counts, field names and reasons; your values stay yours:

{
  "ok": true,
  "dryRun": true,
  "line": "2 rows read · 1 would land as executed shipments · 1 would be held back. Dry run — the workspace stays as it was.",
  "rowsRead": 2,
  "wouldLand": 1,
  "duplicatesInBatch": 0,
  "fieldsRecognised": [
    "carrierCostEur",
    "customer",
    "date",
    "destination",
    "equipment",
    "km",
    "origin",
    "shipperRateEur",
    "sourceReference"
  ],
  "columnsUnread": [],
  "skipped": [
    {
      "row": 2,
      "reason": "Carries what the carrier was paid. Executed history holds what the shipper was charged."
    }
  ]
}

Where common columns land

Their column saysIt lands as
From · Loading place · Pickup · Abgangsortorigin
To · Delivery city · Dropoff · Empfangsortdestination
Load date · Shipment date · Datum · Execution datedate
Sell rate · Revenue · Invoiced · VerkaufspreisshipperRateEur
Buy rate · Carrier cost · Unit_Cost · EinkaufspreiscarrierCostEur
Rate · Price · Preis · Amount · Freighta money value — a person confirms which side it is
Client · Shipper · Account · Kundecustomer
Order number · Consignment · Auftragsnummerreference
ID · Record id · UUIDsourceReference
Trailer type · Vehicle type · Body typeequipment
Distance · Mileage · KMkm
Currency · CCY · Währungcurrency

Columns are mapped once per connection and remembered. A money column that names no side (Rate, Price, Preis, Amount) waits for a person to say whether it is the billed side or the paid side.

How results come back

Connections with outbound enabled receive tender results as JSON: when a round closes or an award is accepted, the tender's lanes, the awarded companies, their splits and agreed volumes — the sender's own data only. Deliveries retry with backoff, and every run in either direction is a sync-log line the workspace can read.

For your AI agent

Hand it the integration skill file — the contract, the doors, the dry-run loop and the mirroring semantics in one page — and it builds your side against us. Agents can also work a workspace directly over the Model Context Protocol; access is minted inside Tendered, in Setup.

Published by freight desks on Tendered.