# Export presets

> The built-in export mappings preset-sdworx (SD Worx concept), preset-generic (generic CSV per day), preset-generic-xml and preset-generic-fixed: full JSON, real output, and their limitations.

URL: https://timetracking.tech/developers/data-out/presets
Last updated: 2026-10-24

Two mappings are built in. Use them directly, or copy one in the dashboard ("Export" → "Exportformaten beheren" → "Beginnen vanaf") and edit the copy. See [export mappings](https://timetracking.tech/developers/data-out/export-mappings).

| `mappingId` | Name | Status | Use for |
|---|---|---|---|
| `preset-sdworx` | SD Worx — variabele looncomponenten (concept) | **Live, concept**: wage codes are placeholders | Starting point for SD Worx variable wage components |
| `preset-generic` | Generiek CSV (per dag) | Live | Spreadsheets, BI, iPaaS, as the base for any custom format |
| `preset-generic-xml` | Generiek XML (per dag) | Live | Same columns as `preset-generic` as XML (`<timesheet><line>…`); see [fixed-width and XML](https://timetracking.tech/developers/data-out/export-mappings#fixed-width-and-xml-files) |
| `preset-generic-fixed` | Generiek TXT vaste breedte (per kracht en uursoort) | Live | Fixed-width TXT, Windows-1252: employee number (8, zero-padded), name (30), hour type (20), hours (8, right), date YYYYMMDD (8) |

The CLI default (`tt export`) and the MCP default (`export_preview`) are `preset-sdworx`.

## `preset-sdworx`

One line per employee per hour type for the whole range. Semicolon-separated, Dutch decimals, UTF-8 with BOM, CRLF.

```json
{
  "id": "preset-sdworx",
  "name": "SD Worx — variabele looncomponenten (concept)",
  "format": "csv",
  "delimiter": ";",
  "includeHeader": true,
  "encoding": "utf-8-bom",
  "lineEnding": "crlf",
  "groupBy": ["employeeNumber", "hourType"],
  "columns": [
    { "header": "Werknemersnummer", "source": "employeeNumber" },
    { "header": "Naam", "source": "employeeName" },
    { "header": "Looncomponent", "source": "hourType", "transform": { "kind": "map", "table": "wageCodes" } },
    { "header": "Aantal", "source": "minutes", "transform": { "kind": "hours_decimal", "decimals": 2, "decimalSeparator": "," } },
    { "header": "Bedrag", "source": "amountCents", "transform": { "kind": "cents_decimal", "decimalSeparator": "," } },
    { "header": "Ingangsdatum", "source": "date", "transform": { "kind": "date", "format": "DD-MM-YYYY" } }
  ],
  "tables": {
    "wageCodes": {
      "normal": "[CODE_NORMAAL]", "overtime_125": "[CODE_OW125]", "overtime_150": "[CODE_OW150]",
      "ort_night": "[CODE_ORT_NACHT]", "ort_evening": "[CODE_ORT_AVOND]", "ort_saturday": "[CODE_ORT_ZATERDAG]", "ort_sunday": "[CODE_ORT_ZONDAG]",
      "holiday": "[CODE_FEESTDAG]", "allowance_travel": "[CODE_REISKOSTEN]",
      "expense_km": "[CODE_KM]", "expense_travel_time": "[CODE_REISUREN]", "expense_public_transport": "[CODE_OV]",
      "expense_parking": "[CODE_PARKEREN]", "expense_meal": "[CODE_MAALTIJD]", "expense_other": "[CODE_OVERIG]",
      "leave_vacation": "[CODE_VAKANTIE]", "leave_sick": "[CODE_ZIEK]", "leave_special": "[CODE_BIJZONDER]", "leave_unpaid": "[CODE_ONBETAALD]"
    }
  },
  "validation": [
    { "column": "Werknemersnummer", "required": true, "pattern": "^\\d+$" },
    { "column": "Looncomponent", "required": true },
    { "column": "Aantal", "required": true, "min": 0, "max": 400 }
  ]
}
```

Real preview output (week 2026-11-30, two approved days of 8.00 h and 7.50 h):

```csv
Werknemersnummer;Naam;Looncomponent;Aantal;Bedrag;Ingangsdatum
1004;Sanne Janssen;[CODE_NORMAAL];15,50;;01-12-2026
```

Before going live:

1. Copy the preset and replace every `[CODE_…]` with your SD Worx wage component codes. Check the column names and order against your SD Worx import template with your SD Worx consultant. The preset is a concept until the real template is confirmed.
2. Hour types missing from `wageCodes` (for example custom rule-pack types or `allowance_<code>`) become empty, and the `required` rule on "Looncomponent" then blocks the commit. Add them.
3. "Ingangsdatum" is the **first** day of each group (see [grouping](https://timetracking.tech/developers/data-out/export-mappings#grouping)). If SD Worx expects the period start, keep exporting exactly one payroll period per run.
4. Employee numbers must be digits only (`^\d+$`).

Guide: [SD Worx integration](https://timetracking.tech/developers/integrations/payroll/sd-worx).

## `preset-generic`

One line per person × day × hour type, with ISO dates and decimal hours using a point.

```json
{
  "id": "preset-generic",
  "name": "Generiek CSV (per dag)",
  "format": "csv",
  "delimiter": ";",
  "includeHeader": true,
  "encoding": "utf-8-bom",
  "lineEnding": "crlf",
  "columns": [
    { "header": "employee_number", "source": "employeeNumber" },
    { "header": "employee_name", "source": "employeeName" },
    { "header": "client", "source": "clientName" },
    { "header": "placement", "source": "placementRef" },
    { "header": "date", "source": "date", "transform": { "kind": "date", "format": "YYYY-MM-DD" } },
    { "header": "hour_type", "source": "hourType" },
    { "header": "hours", "source": "minutes", "transform": { "kind": "hours_decimal", "decimals": 2 } }
  ],
  "tables": {},
  "validation": [{ "column": "employee_number", "required": true }]
}
```

Real committed output:

```csv
employee_number;employee_name;client;placement;date;hour_type;hours
1004;Sanne Janssen;Bakkerij Ruijters;PL-2026-104;2026-12-01;normal;8.00
1004;Sanne Janssen;Bakkerij Ruijters;PL-2026-104;2026-12-02;normal;7.50
```

Limitations:

- **No amount column.** Expense and allowance lines (`expense_*`, `allowance_*`) appear with `hours` `0.00` (or travel-time hours), and their money amount is lost. Copy the preset and add `{"header":"amount","source":"amountCents","transform":{"kind":"cents_decimal"}}` when you export expenses.
- Leave lines have an empty `client` and `placement`.

## XLSX and JSON

Every committed run can be downloaded from the dashboard ("Export" → previous exports) as the mapped file, as **XLSX** (`?as=xlsx`, the same rows in one sheet) or as **JSON** (`?as=json`, an array of objects keyed by header). Over the API, `GET /exports/runs/{id}/file` returns the mapped file. For JSON-shaped data, use `pay_lines` from `GET /exports/runs/{id}`.
