> ## Documentation Index
> Fetch the complete documentation index at: https://docs.upwell.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Syncing foundation entities

> Push customers, carriers, shipments, and bills from your TMS to Upwell — the prerequisite data that makes AP and AR work.

# Syncing foundation entities

Before carrier invoices can match or customer invoices can bill, Upwell needs the data they reference: **customers**, **carriers**, **shipments**, and (for AP) **bills**. This page covers how to push those records from your TMS.

<Note>
  If you haven't read it yet, start with [Core concepts & data model](/concepts/data-model) — it defines every object mentioned here and how they connect. For patterns that apply to every endpoint (integer-cents money, the `input` wrapper, the presigned upload), see [Integration patterns](/integration-patterns).
</Note>

## Sync order

Entities reference each other, so push them in dependency order:

<Steps>
  <Step title="Customers and carriers">
    These two are independent — sync them in any order (or in parallel). Everything downstream needs at least one of them.
  </Step>

  <Step title="Shipments">
    A shipment references a customer and a carrier by their Upwell IDs (`customerId`, `carrierId`). Sync those first, store the returned IDs, then sync shipments.
  </Step>

  <Step title="Bills (AP only)">
    A bill references a shipment and a carrier. Optional for AR-only integrations.
  </Step>

  <Step title="Invoices, carrier invoices, payments">
    These are the transactional records — each guide has its own page: [Customer invoices (AR)](/api-guides/customer-invoices), [Carrier invoice submission (AP)](/api-guides/carrier-invoice-submission), [Customer payments](/api-guides/customer-payments).
  </Step>
</Steps>

## Customers

`POST /api/rest/customers` creates a customer (shipper). Store the returned `id` — you'll need it on shipments and invoices.

```bash theme={null}
curl -X POST https://api.upwell.com/api/rest/customers \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "name": "Acme Manufacturing",
      "sourceSystem": "YOUR_TMS",
      "sourceSystemId": "CUST-10042",
      "emailAddress": "ap@acme-mfg.com",
      "paymentDiscountTerms": "Net 30"
    }
  }'
```

| Field                  | Required    | Notes                                                                                                       |
| ---------------------- | ----------- | ----------------------------------------------------------------------------------------------------------- |
| `name`                 | Yes         | Customer display name.                                                                                      |
| `sourceSystem`         | Recommended | Your TMS identifier constant — enables upsert-by-source-system-id.                                          |
| `sourceSystemId`       | Recommended | Your TMS's primary key for this customer. Together with `sourceSystem`, this is the unique external handle. |
| `emailAddress`         | Recommended | Used for invoice delivery if sending invoices from Upwell.                                                  |
| `paymentDiscountTerms` | No          | Payment terms string (e.g. `"Net 30"`). Drives AR aging and reminder timing.                                |

To update an existing customer, use `PUT /api/rest/customers/{id}` (by Upwell ID) or `PUT /api/rest/customers` with `sourceSystem` + `sourceSystemId` in the body to update by your external key.

<Warning>
  `POST` is **not** idempotent for customers — re-posting a `(sourceSystem, sourceSystemId)` pair that already exists returns a `400 Uniqueness violation`. Use `POST` for first sync, `PUT` for updates. See [Integration patterns](/integration-patterns#idempotent-upserts-via-sourcesystem--sourcesystemid).
</Warning>

## Carriers

`POST /api/rest/carriers` creates a carrier. Same pattern as customers.

```bash theme={null}
curl -X POST https://api.upwell.com/api/rest/carriers \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "name": "Fast Freight LLC",
      "sourceSystem": "YOUR_TMS",
      "sourceSystemId": "CAR-2088",
      "mcNumber": "MC-123456",
      "dotNumber": "1234567",
      "scacNumber": "FFRT",
      "email": "billing@fastfreight.com",
      "phone": "555-0200",
      "currency": "USD"
    }
  }'
```

| Field                             | Required    | Notes                                                                                                     |
| --------------------------------- | ----------- | --------------------------------------------------------------------------------------------------------- |
| `name`                            | Yes         | Carrier display name.                                                                                     |
| `sourceSystem` / `sourceSystemId` | Recommended | External key pair — same pattern as customers.                                                            |
| `mcNumber`                        | No          | Motor carrier number.                                                                                     |
| `dotNumber`                       | No          | DOT number.                                                                                               |
| `scacNumber`                      | No          | Standard carrier alpha code. Helps Upwell match carrier invoices that reference a SCAC instead of a name. |
| `email`, `phone`                  | No          | Contact info.                                                                                             |

Updates: `PUT /api/rest/carriers/{id}` (by Upwell ID) or `PUT /api/rest/carriers` (by `sourceSystem` + `sourceSystemId` in the request body).

## Shipments

`POST /api/rest/shipments` creates a shipment (load). A shipment ties together a customer and a carrier and is the hub that invoices, bills, and documents hang off.

```bash theme={null}
curl -X POST https://api.upwell.com/api/rest/shipments \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "shipmentId": "YOUR_TMS-SH-50012",
      "sourceSystem": "YOUR_TMS",
      "sourceSystemId": "SH-50012",
      "customerId": "cus_abc123",
      "carrierId": "car_def456",
      "customerTotalRate": 450000,
      "carrierTotalRate": 350000,
      "pickupAt": "2026-07-15T08:00:00Z",
      "deliveredAt": "2026-07-18T14:00:00Z",
      "carrierProNumber": "PRO-44120",
      "customerPoNumber": "PO-88001",
      "billOfLadingNumber": "BOL-77123",
      "referenceNumbers": "REF-001,REF-002",
      "status": "DELIVERED",
      "mode": "TL"
    }
  }'
```

| Field                             | Required    | Notes                                                                                                               |
| --------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------- |
| `shipmentId`                      | **Yes**     | A unique string identifier — `NOT NULL`, no server default. Generate from your own key, e.g. `"YOUR_TMS-SH-50012"`. |
| `sourceSystem` / `sourceSystemId` | Recommended | External key pair.                                                                                                  |
| `customerId`                      | Recommended | Upwell customer ID (`cus_…`). Links the shipment to AR.                                                             |
| `carrierId`                       | Recommended | Upwell carrier ID (`car_…`). Links the shipment to AP.                                                              |
| `customerTotalRate`               | Recommended | What you charge the customer, in **integer cents**. `$4,500.00` → `450000`.                                         |
| `carrierTotalRate`                | Recommended | What you owe the carrier, in **integer cents**.                                                                     |
| `carrierProNumber`                | Recommended | Carrier PRO number — the strongest match key Upwell uses to match inbound carrier invoices to shipments.            |
| `customerPoNumber`                | No          | Customer purchase order number.                                                                                     |
| `billOfLadingNumber`              | No          | Bill of lading number.                                                                                              |
| `referenceNumbers`                | No          | Comma-separated additional references.                                                                              |
| `pickupAt`, `deliveredAt`         | No          | ISO 8601 timestamps.                                                                                                |
| `status`                          | No          | Shipment status string (e.g. `DELIVERED`, `IN_TRANSIT`).                                                            |
| `mode`                            | No          | Freight mode (`TL`, `LTL`, `INTERMODAL`, etc.).                                                                     |

<Warning>
  `shipmentId` is **required** and has no server default — omitting it returns a `400 constraint-violation`. This is different from the `id` Upwell assigns (like `shi_abc123`); `shipmentId` is your own human-readable identifier.
</Warning>

Updates: `PUT /api/rest/shipments/{id}`.

## Bills (AP only)

A **bill** is the expected payable — what your TMS says you should owe a carrier for a shipment. When a carrier invoice arrives, Upwell audits it against the bill and flags mismatches as exceptions.

`POST /api/rest/bills` creates a bill:

```bash theme={null}
curl -X POST https://api.upwell.com/api/rest/bills \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "sourceSystem": "YOUR_TMS",
      "sourceSystemId": "BILL-30044",
      "carrierId": "car_def456",
      "proNumber": "YOUR_TMS-SH-50012",
      "referenceNumber": "REF-30044",
      "totalAmount": 350000,
      "currency": "USD",
      "issueDate": "2026-07-10",
      "dueDate": "2026-08-09",
      "status": "OPEN"
    }
  }'
```

| Field                             | Required    | Notes                                                                                                                                                                                                                                            |
| --------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `sourceSystem` / `sourceSystemId` | Recommended | External key pair.                                                                                                                                                                                                                               |
| `carrierId`                       | Recommended | Links the bill to a carrier.                                                                                                                                                                                                                     |
| `proNumber`                       | Recommended | The shipment/load identifier — must match the target shipment's `shipmentId` value so Upwell can link the bill to the shipment for audit comparison. This is **not** the carrier's PRO number (that goes on the shipment as `carrierProNumber`). |
| `referenceNumber`                 | No          | Your internal reference number for this bill.                                                                                                                                                                                                    |
| `totalAmount`                     | Recommended | Expected payable in **integer cents**. This is the amount Upwell compares against the carrier invoice during audit.                                                                                                                              |
| `issueDate`                       | No          | Bill issue date (`YYYY-MM-DD`).                                                                                                                                                                                                                  |
| `dueDate`                         | No          | Payment due date (`YYYY-MM-DD`).                                                                                                                                                                                                                 |
| `currency`                        | No          | Defaults to `USD`.                                                                                                                                                                                                                               |
| `status`                          | No          | Bill status.                                                                                                                                                                                                                                     |

Updates: `PUT /api/rest/bills/{id}`.

<Tip>
  Bills are optional for carrier-invoice processing — Upwell can still receive and classify carrier invoices without a matching bill. But without a bill, the exception audit can't compare expected vs. actual amounts, so you won't get amount-mismatch exceptions. If your TMS tracks expected carrier costs, push them as bills.
</Tip>

## Keeping records in sync

Most TMS integrations run a two-phase sync:

1. **Initial load** — push all active customers, carriers, and shipments via `POST`. Store the returned Upwell IDs in your system.
2. **Ongoing sync** — when a record changes in your TMS, push the update via `PUT`. You can update by Upwell ID (`PUT /api/rest/<resource>/{id}`) or by source-system key (`PUT /api/rest/<resource>` with `sourceSystem` + `sourceSystemId` in the body).

<AccordionGroup>
  <Accordion title="Webhook-push (real-time)">
    Your TMS fires a webhook on every create/update, and your integration pushes the change to Upwell immediately. This is the lowest-latency option — records are usually in Upwell within seconds. Best for TMS platforms with outbound webhook support.
  </Accordion>

  <Accordion title="Scheduled batch (periodic)">
    A cron job queries your TMS for records changed since the last run and pushes them to Upwell in bulk. Simpler to build; latency depends on your schedule (typically 5–15 minutes). Best for TMS platforms with a "changed since" query API.
  </Accordion>

  <Accordion title="API-pull (Upwell-initiated)">
    Upwell calls your TMS's API on a schedule to pull new/changed records. Requires your TMS to expose a query API. Contact Upwell to set this up.
  </Accordion>
</AccordionGroup>

## What's next

Once foundation entities are in Upwell, you can build on top of them:

<CardGroup cols={2}>
  <Card title="Customer invoices (AR)" icon="file-invoice" href="/api-guides/customer-invoices">
    Create customer invoices tied to shipments.
  </Card>

  <Card title="Carrier invoice submission (AP)" icon="file-lines" href="/api-guides/carrier-invoice-submission">
    Submit carrier invoices for audit and matching.
  </Card>

  <Card title="Shipment documents" icon="file-pdf" href="/api-guides/shipment-documents">
    Attach BOLs, PODs, and other documents to shipments.
  </Card>

  <Card title="Customer payments" icon="money-bill" href="/api-guides/customer-payments">
    Record remittances from customers.
  </Card>
</CardGroup>
