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

# DSV

> Pull DSV invoices with their charge line items and the shipments they bill, for air, sea and rail freight.

<Note>
  **Beta** — This connection is in beta and may change.
</Note>

DSV is a global freight forwarder. Connecting DSV to Duvo lets your agents pull invoices **with their individual charge lines** and the shipments each invoice bills, so an invoice can be matched to its shipment and re-rated without a second lookup or a manual portal export.

<Note>
  Coverage is **air, sea and rail only**. DSV road freight is billed over EDI and is not visible through this API. See [What this connection cannot do](#what-this-connection-cannot-do).
</Note>

## Setup

Setup needs two DSV subscriptions, both approved by DSV, plus your myDSV login. Start the subscriptions before you need the connection — DSV reviews each one and does not publish a turnaround time.

<Steps>
  <Step title="Confirm prerequisites" icon="circle-check">
    <Check>A myDSV account. Its username and password *are* the API credentials — DSV's OAuth takes them directly, so there is no separate application or consumer key to create.</Check>
    <Check>An account on the [DSV Developer Portal](https://developer.dsv.com/). Registration is self-service.</Check>
    <Check>Your DSV customer code, called the **MDM code**. DSV assigns it when your account is set up and it appears on your DSV invoices.</Check>

    <Tip>
      Use a dedicated DSV service login rather than a person's. Because the password *is* the credential, the connection stops working the day that person rotates their password or leaves.
    </Tip>
  </Step>

  <Step title="Subscribe to both API products" icon="key">
    On the Developer Portal, under **Products**, subscribe to both:

    * **Fetch DSV Access token** — issues the OAuth token. Subscribing to the invoice product alone does not grant token issuance.
    * **Invoice — Air, Sea, Rail** — the invoice data itself.

    Each subscription is reviewed by DSV. Subscribing to one does not grant the other.

    <Warning>
      DSV scopes a subscription key to a **single API product**, so the two products issue **two different keys**. They are not interchangeable — sending the invoice key to the token endpoint fails at the gateway, and vice versa.
    </Warning>
  </Step>

  <Step title="Collect both subscription keys" icon="copy">
    Once DSV approves a subscription, its keys appear on your **Profile** page on the portal. Each product gives you a primary and a secondary key.

    Use each product's **primary** key in its own field: the keys are product-specific, and DSV rejects a token key sent to the invoice product. Keep each secondary key so you can rotate without downtime.
  </Step>

  <Step title="Add the connection in Duvo" icon="plug">
    On the [Connections page](https://app.duvo.ai/integrations), open DSV and fill in these fields:

    <ParamField body="myDSV Username" type="string" required>
      The email address you sign in to myDSV with. DSV's OAuth uses it as the `client_id`.
    </ParamField>

    <ParamField body="myDSV Password" type="string" required>
      The password for that login, used as the `client_secret`. Prefer a service login over a person's — see the tip above.
    </ParamField>

    <ParamField body="Access Token Subscription Key" type="string" required>
      Primary key for the **Fetch DSV Access token** product.
    </ParamField>

    <ParamField body="Invoice Subscription Key" type="string" required>
      Primary key for the **Invoice** product. This is a different value from the one above.
    </ParamField>

    <ParamField body="Customer Code" type="string" required>
      Your DSV customer identifier (MDM code) — for example `10123456`. Used as the default for invoice queries; individual requests can override it.
    </ParamField>

    <ParamField body="Environment" type="string">
      Leave empty for production. Enter `demo` to target DSV's demo product instead. The demo and production products are subscribed to separately.
    </ParamField>
  </Step>
</Steps>

<AccordionGroup>
  <Accordion title="Production access is not self-service" icon="triangle-alert">
    The Developer Portal lists **demo products only**. Production access is an "apply to go live" request to DSV rather than a subscription you can add yourself.

    Plan for that step: a working demo connection does not automatically become a production one.
  </Accordion>

  <Accordion title="Why two subscription keys" icon="key">
    DSV's gateway requires a `DSV-Subscription-Key` header on **every** call, including the token exchange, and scopes each key to one API product.

    So the token call carries the Access Token product's key and the invoice call carries the Invoice product's key. Duvo sends the right one on each request; you only need to paste them into the matching fields. If you swap them, DSV rejects the calls at the gateway before your username and password are ever read.
  </Accordion>

  <Accordion title="Date filters and the default window" icon="calendar">
    With no invoice date filters, DSV returns the **last 30 days**. If you supply only a start date it uses today as the end; only an end date and it goes back 30 days from there.

    Invoice dates cannot be in the future. Payment **due** dates can, and are how you find invoices that are not yet payable.
  </Accordion>

  <Accordion title="Third-party documentation" icon="book">
    * [DSV Developer Portal](https://developer.dsv.com/) — registration, product subscriptions, and your subscription keys.
    * [DSV API overview](https://www.dsv.com/en/why-dsv/connectivity/dsv-api) — the API programme and available products.
    * [myDSV](https://my.dsv.com/) — the customer portal, where invoice PDFs and road-freight billing live.
  </Accordion>
</AccordionGroup>

## Capabilities

* **List invoices with charge lines** — retrieve invoices for a customer code, each carrying its individual charge line items rather than just a header total, so an invoice total can be broken down and re-rated.
* **Match an invoice to its shipment without a second call** — every invoice embeds the shipments it bills, with house bill, master bill, carrier and SCAC, order numbers and customer references.
* **Compare across three currencies** — each charge line carries the invoice amount, the amount as charged, and the booking country's local amount, plus the exchange rate and per-currency tax that reconcile them. Comparing the wrong pair turns a currency conversion into a phantom overcharge, so all three are kept.
* **Filter by date, due date and transport mode** — narrow by invoice date range, payment due date range, or a single mode (air, sea or rail).
* **Page through large result sets** — results are cursor-paged, and an agent is told when more pages are available. A page too large for one result is refused whole, with the page size to start again with, rather than trimmed behind the cursor. A single invoice that alone exceeds the limit comes back header-only, with its counts and PDF link, so the walk continues.
* **Reach the source document** — each invoice carries a link to its PDF for dispute evidence.

## What this connection cannot do

Being explicit here saves a wasted agent run:

* **No road freight.** Coverage is air, sea and rail. DSV bills European road freight over EDI, and none of it appears through this API. If a meaningful share of your DSV spend is road, this connection will not see it — check the split before relying on it for a total.
* **No production self-service.** The portal only offers demo products; going live is a request to DSV.
* **No PDF retrieval.** Every invoice carries a link to its PDF, and that link is all the connection returns — Duvo does not download the document. DSV publishes an endpoint for it, so the gap is on our side, not the API's.
* **One operation: the filtered invoice list.** DSV also exposes invoice-by-id, invoice-by-shipment-id and invoice-by-customer-reference endpoints; none of them is wired up. To find a single invoice, filter the list by date range and match on the invoice id or shipment reference in the result.
* **Credit-note identification is unconfirmed.** Invoices carry a document type, but DSV publishes no list of its values, so the field is passed through when it is a string (anything else becomes null) and telling a credit note from an invoice has not been verified against live data.

## Key Benefits

* **Re-rating on real charge detail** — charge line items mean an overcharge can be found in the line that caused it, not inferred from a total.
* **No shipment-to-invoice join to build** — the shipment references arrive inside the invoice, so matching does not need a second system.
* **Currency-aware by default** — the three amount columns and the exchange rate are all carried, so a conversion is not mistaken for a discrepancy.
* **Clear failure messages** — a rejected login, a key sent to the wrong product, and an unapproved subscription each report differently, so setup problems are quick to place.

## Works Well With

<CardGroup cols={3}>
  <Card title="Google Sheets" icon="https://mintcdn.com/duvo-d8027998/O3tlM6eCuFk2uJpN/images/connections/google-sheets.svg?fit=max&auto=format&n=O3tlM6eCuFk2uJpN&q=85&s=0ef8d55e05c34e7a4a618933bdf0ceb3" href="/user-guide/connections/available-connections/google-sheets" width="24" height="24" data-path="images/connections/google-sheets.svg">
    Build freight spend summaries or charge-variance trackers from invoice line data.
  </Card>

  <Card title="Microsoft Excel" icon="https://mintcdn.com/duvo-d8027998/O3tlM6eCuFk2uJpN/images/connections/excel.svg?fit=max&auto=format&n=O3tlM6eCuFk2uJpN&q=85&s=986599d60d09acee47293fda2b62df99" href="/user-guide/connections/available-connections/microsoft-excel" width="2290" height="2130" data-path="images/connections/excel.svg">
    Reconcile DSV charge lines against contracted rates or internal accruals.
  </Card>

  <Card title="Maersk" icon="https://mintcdn.com/duvo-d8027998/ycAgv1Qg61bsv5xV/images/connections/maersk.svg?fit=max&auto=format&n=ycAgv1Qg61bsv5xV&q=85&s=5475f5915fdfee3aaaea1079c4309cf4" href="/user-guide/connections/available-connections/maersk" width="48" height="48" data-path="images/connections/maersk.svg">
    Cover ocean carrier invoices alongside forwarder invoices for a fuller spend picture.
  </Card>

  <Card title="EDI" icon="https://mintcdn.com/duvo-d8027998/2reMGTvJRCnV9FEF/images/connections/edi.png?fit=max&auto=format&n=2reMGTvJRCnV9FEF&q=85&s=3d4fe5901208e4982d807c1a3fd440d8" href="/user-guide/connections/available-connections/edi" width="512" height="512" data-path="images/connections/edi.png">
    Reach the road-freight billing this API does not cover.
  </Card>

  <Card title="Slack" icon="https://mintcdn.com/duvo-d8027998/O3tlM6eCuFk2uJpN/images/connections/slack.svg?fit=max&auto=format&n=O3tlM6eCuFk2uJpN&q=85&s=8a64bdd1af39e903923e4a273b4a4618" href="/user-guide/connections/available-connections/slack" width="512" height="512" data-path="images/connections/slack.svg">
    Alert the team when a charge line falls outside its expected range.
  </Card>

  <Card title="Enterprise Browser" icon="https://mintcdn.com/duvo-d8027998/O3tlM6eCuFk2uJpN/images/connections/browser-agent.svg?fit=max&auto=format&n=O3tlM6eCuFk2uJpN&q=85&s=49168ae85c39df2529060d2f33df88b2" href="/user-guide/connections/available-connections/browser" width="24" height="24" data-path="images/connections/browser-agent.svg">
    Retrieve invoice PDFs from myDSV when the API link is not enough.
  </Card>
</CardGroup>
