Generic Reporting API
The Generic Reporting API enables organizations to create fully customized data exports for manual review or automated import into payroll systems. It provides a flexible query-based approach where you specify row types, columns, filters, and output formats to generate exactly the data you need.
Overview
Unlike the fixed report endpoints, the Generic Reporting API lets you compose exports dynamically by combining three core concepts:
- Types — Define what data to export (each type generates a row per employee). Examples:
credit-time,debit-time,absence. - Columns — Define which fields appear in each row. Examples:
first-name,last-name,accounting-number,value. - Date Range — The time period the export covers.
The result is a table where each row represents one type per employee, and each column contains the requested field value.
The Generic exporter is part of the shared export framework that also powers the fixed-format Sage and DATEV exporters — see Exports for an overview of the framework.
List Available Exporters
Returns a map of all available exporter names to their endpoint URLs.
Request
curl -X GET "https://api.zeitstrom.com/api/v2/exports/" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Response
{
"sage": "https://api.zeitstrom.com/api/v2/exports/sage/",
"datev": "https://api.zeitstrom.com/api/v2/exports/datev/",
"generic": "https://api.zeitstrom.com/api/v2/exports/generic/",
"multi": "https://api.zeitstrom.com/api/v2/exports/multi/"
}
Generate an Export
Generate a customized data export with the Generic exporter.
Query Parameters
- Name
daterange- Type
- string
- Description
The date range for the export, pipe-separated:
YYYY-MM-DD|YYYY-MM-DD.
- Name
types- Type
- string
- Description
Row types to include, pipe-separated. Each type generates one row per employee. Use the discovery endpoint to see all available types. If omitted, the export contains no rows.
- Name
columns- Type
- string
- Description
Columns to include in the output, pipe-separated. Use the discovery endpoint to see all available columns. If omitted, the export contains no columns.
- Name
export_format- Type
- string
- Description
Output format:
csv,json,table,plain, orxlsx. Defaults tocsv. The binaryxlsxformat requiresresponse_only=true.
- Name
employee_ids- Type
- string
- Description
Restrict the export to specific employees, as a pipe-separated list of employee UUIDs. Unknown or inaccessible IDs cause a validation error listing the missing IDs.
- Name
employee_group_ids- Type
- string
- Description
Restrict the export to specific departments, as a pipe-separated list of group UUIDs. When combined with
employee_ids, the two are OR-combined: employees matching either list are included.
- Name
filter- Type
- string
- Description
Filter employees by attributes such as custom fields. Multiple filters must be pipe-separated within this single parameter. See Filtering.
- Name
skip_zero_rows- Type
- boolean
- Description
Whether to omit rows with a zero value. Defaults to
true. Rows of theabsencetype are always kept, even when their value is zero.
- Name
response_only- Type
- boolean
- Description
Defaults to
false, which returns a JSON envelope containing both the request parameters and the export data. Set totrueto receive only the export itself as a file download, with the content type derived from the export format. Required forxlsx.
- Name
prefix- Type
- string
- Description
A Base64-encoded string prepended to the output. Only supported for the
csv,plain, andtableformats. The decoded string may contain the template variables{first_day:<strftime>}and{last_day:<strftime>}— e.g.Export {first_day:%Y%m%d};encodes toRXhwb3J0IHtmaXJzdF9kYXk6JVklbSVkfTs=.
- Name
is_async- Type
- boolean
- Description
Set to
trueto generate the export in a background task instead of synchronously. See Asynchronous Exports.
Basic Export
curl -X GET "https://api.zeitstrom.com/api/v2/exports/generic/?daterange=2024-09-01|2024-09-30&types=credit-time&columns=first-name|last-name|value&export_format=json" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Response
{
"request": {
"is_async": false,
"skip_zero_rows": true,
"exporter": "generic",
"export_format": "json",
"daterange": ["2024-09-01", "2024-09-30"],
"employee_ids": null,
"types": ["credit-time"],
"columns": ["first-name", "last-name", "value"],
"response_only": false,
"prefix": null,
"filter": null
},
"response": [
{
"first-name": "Max",
"last-name": "Mustermann",
"value": "576000.000"
},
{
"first-name": "Erika",
"last-name": "Musterfrau",
"value": "547200.000"
}
]
}
With the default response_only=false, every response is wrapped in a {request, response} envelope and served as application/json — even for csv output, where the CSV appears as a string in the response field. Set response_only=true to receive only the raw export.
Multiple Types
curl -X GET "https://api.zeitstrom.com/api/v2/exports/generic/?daterange=2024-09-01|2024-09-30&types=credit-time:hours|debit-time:hours&columns=first-name|last-name|accounting-number|value&export_format=csv&response_only=true" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Values for time-based types are returned in seconds by default (except absence, which defaults to hours). Pass a unit as the first type attribute — s, m, h, or d (long forms like hours also work) — to convert the value, e.g. credit-time:hours.
Column Customization
Columns support several advanced features for formatting, renaming, and combining values.
Header Renaming
Rename any column header in the output using the > operator:
first-name>Vorname
This outputs the first-name column but labels it "Vorname" in the header row.
Renamed Headers
curl -X GET "https://api.zeitstrom.com/api/v2/exports/generic/?daterange=2024-09-01|2024-09-30&types=credit-time:hours&columns=first-name>Vorname|last-name>Nachname|value>Stunden&export_format=csv" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Column Parameters
Some columns accept parameters using the : separator:
custom-field:mandator
This outputs the employee's custom field mandator. Similarly, physical-token:-5 returns the last 5 digits of the employee's physical token. Row types accept attributes with the same syntax (e.g. credit-time:hours).
Number Formatting
Numeric values are rendered as decimal strings using the format #0.000 and the en locale by default (e.g. "576000.000"). Override this per column with the number/format/... and number/locale/... configuration attributes:
value:number/format/@0.00:number/locale/de
Use @ in place of # in the format string — it is substituted server-side and avoids # starting a URL fragment.
Modifiers
Apply string modifiers to transform column values using the :m/ syntax:
accounting-number:m/rfill/8/0
This right-fills the accounting-number value with zeros to a total length of 8 characters.
Use the modifiers discovery endpoint to see all available modifiers.
Column Concatenation
Combine multiple columns into a single output column using the ^ operator:
first-name^static: ^last-name>Full Name
This concatenates first-name, a literal space (via static: ), and last-name into a single column labeled "Full Name".
Concatenated Columns
curl -X GET "https://api.zeitstrom.com/api/v2/exports/generic/?daterange=2024-09-01|2024-09-30&types=credit-time:hours&columns=first-name^static: ^last-name>Name|accounting-number:m/rfill/8/0>Lohnart|value>Stunden&export_format=csv" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Type and column expressions often contain characters that must be URL-encoded in production requests: spaces (%20), > (%3E), ^ (%5E), and | (%7C). With curl, use -G together with --data-urlencode to encode parameters automatically. The examples on this page show parameters unencoded for readability.
Row Types and Salary Classes
Row Types
Each type represents a category of data to export. When you specify multiple types separated by pipes, the export generates one row per type per employee:
types=credit-time:hours|debit-time:hours|absence:h:holiday
This produces up to three rows per employee — one for each type that has data.
Absence Types
The absence type takes positional attributes: absence:<unit>:<missing-type>:<aggregation>:<balance-impact>. The unit is s, m, h, or d. Unlike the other time-based types, the absence type defaults to h (hours). The missing type is one or more comma-separated absence type IDs configured for your institution (e.g. holiday, sick, parental_leave). For example, absence:h:sick returns the hours an employee was sick in the given date range. See the types discovery endpoint for the full attribute reference.
Salary Classes (Lohnarten)
You can assign salary class identifiers to row types using the > operator on the type. This populates the key column:
types=credit-time:hours>S|debit-time:hours>H
Here, credit-time rows get key "S" and debit-time rows get "H". This is useful for payroll integrations that require salary class codes.
With Salary Classes
curl -X GET "https://api.zeitstrom.com/api/v2/exports/generic/?daterange=2024-09-01|2024-09-30&types=credit-time:hours>100|debit-time:hours>200|absence:h:holiday>300&columns=accounting-number|key|value&export_format=csv" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Row Aggregation
Rows that are identical in every column except the cumulative value (and param:days) columns are merged into a single row, with their values summed. This means the number of output rows depends on which columns you select: for example, exporting only accounting-number|key|value sums all daily rows per employee and salary class into one row each.
value columns also support a limit/<from>,<to>,<default> configuration attribute that restricts rows to an aggregated value range — e.g. value:limit/0,100 drops rows outside 0–100, and value:limit/0,100,0 keeps them with the value replaced by 0.
Filtering
Use the filter query parameter to restrict the export to specific employees or departments. To combine multiple filters, separate them with a pipe within the single filter parameter — do not repeat the parameter, as only the last occurrence would be used.
Filter by Employee
filter=employee_ids=508d5250-7399-4b65-a574-3da53d9ddc25
Filter by Department
filter=employee_group_ids=ab5abc73-33ce-4da1-a900-d743d0bbc3e8
Filter by Custom Field
filter=custom-field:role=non_manager_report
Combining Filters
Multiple filters are pipe-separated within one filter parameter:
Combined Filters
curl -X GET "https://api.zeitstrom.com/api/v2/exports/generic/?daterange=2024-09-01|2024-09-30&types=credit-time:hours&columns=first-name|last-name|value&filter=employee_group_ids=ab5abc73-33ce-4da1-a900-d743d0bbc3e8|custom-field:role=non_manager_report&export_format=json" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Use the filters discovery endpoint to see all available filter options.
CSV Format Options
The CSV export format supports additional configuration via the export_format parameter.
Custom Delimiter
Change the CSV delimiter by specifying it URL-encoded after csv:delimiter>:
export_format=csv:delimiter>%3b
This uses a semicolon (;) instead of the default comma.
Disable Header Row
Suppress the header row in CSV output:
export_format=csv:writeheader>false
Combined Options
CSV with Semicolons and No Header
curl -X GET "https://api.zeitstrom.com/api/v2/exports/generic/?daterange=2024-09-01|2024-09-30&types=credit-time:hours&columns=accounting-number|value&export_format=csv:delimiter>%3b:writeheader>false" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Multi-Export
The Multi-Export endpoint combines multiple export configurations into a single request. Pass a JSON array of export configurations via the config parameter.
Each configuration object in the array may only contain the keys types, columns, and filter — any other key is rejected with a validation error. All other parameters are shared top-level query parameters: daterange (required), export_format, response_only, and an optional fallback filter applied to every configuration that has no filter of its own. The prefix parameter is not supported for Multi-Export.
Multi-Export Request
curl -X GET "https://api.zeitstrom.com/api/v2/exports/multi/?config=[{\"types\":\"credit-time:hours>100\",\"columns\":\"accounting-number|key|value\"},{\"types\":\"debit-time:hours>200\",\"columns\":\"accounting-number|key|value\"}]&daterange=2024-09-01|2024-09-30&export_format=xlsx&response_only=true" \
-H "Authorization: Token <YOUR_API_TOKEN>"
The config parameter value must be a valid JSON array. Remember to URL-encode the value in production requests. As with the Generic exporter, the binary xlsx format requires response_only=true.
Asynchronous Exports
Large exports can take a while to generate. Add is_async=true to any export request to run it as a background task instead: the response immediately returns a task object that you can poll.
Start an Async Export
curl -X GET "https://api.zeitstrom.com/api/v2/exports/generic/?daterange=2024-01-01|2024-12-31&types=credit-time:hours&columns=first-name|last-name|value&export_format=csv&is_async=true" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Task Response
{
"id": "9f2b6c1e-4a3d-4b7e-9c0a-1d2e3f4a5b6c",
"created_at": "2024-10-01T06:15:22.481920",
"finished_at": null,
"status": "created",
"target": null
}
To poll the task, simply repeat the exact same request: identical export requests made within the last 12 hours return the existing task instead of creating a new one. The status progresses from created through in_progress to finished (or error). Once finished, target contains a presigned download URL for the export file, valid for 12 hours:
Finished Task
{
"id": "9f2b6c1e-4a3d-4b7e-9c0a-1d2e3f4a5b6c",
"created_at": "2024-10-01T06:15:22.481920",
"finished_at": "2024-10-01T06:16:05.912344",
"status": "finished",
"target": "https://zeitstrom-exports.s3.amazonaws.com/exports/9f2b6c1e-4a3d-4b7e-9c0a-1d2e3f4a5b6c.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=43200&X-Amz-Signature=..."
}
Discovery Endpoints
The Generic Reporting API provides several discovery endpoints to inspect available types, columns, filters, and modifiers. These endpoints require no authentication and return a human-readable HTML reference — you can open them directly in a browser.
List Available Types
Returns all row types available for the Generic exporter.
Request
curl -X GET "https://api.zeitstrom.com/api/v2/exports/generic/types/"
List Available Columns
Returns all columns available for the Generic exporter.
Request
curl -X GET "https://api.zeitstrom.com/api/v2/exports/generic/columns/"
List Available Filters
Returns all filter options available for the Generic exporter.
Request
curl -X GET "https://api.zeitstrom.com/api/v2/exports/generic/filters/"
List Available Modifiers
Returns all value modifiers that can be applied to columns.
Request
curl -X GET "https://api.zeitstrom.com/api/v2/exports/generic/modifiers/"
Access Control
Exports respect the permissions of the authenticated user. Department leaders only see data for employees in their departments. The set of accessible records determines the scope of the export.
Employees archived before the start of the requested date range are excluded automatically; employees archived during or after the date range are still included.
Exports always query live data — the results reflect the current state of your time tracking data at the moment of the request.