Daily Reports
Daily reports (Tagesberichte) document what happened on a construction site or project on a single calendar day: who was on site and for how long, the weather, subcontractors, activities, material usage, comments, photos, and signatures. A report is identified by the combination of a project and a date — it is not a stored object of its own, but materializes from the individual entries recorded for that day, either authored on site in the mobile app or filled in automatically from time tracking.
If your API token is restricted to specific permissions, it needs the
matching scope for each operation: daily_reports:view for all GET
requests, and daily_reports:edit for the autofill and photo-upload-token
endpoints. Autofilling a report that has already been submitted or approved
additionally requires daily_reports:approve; autofilling an archived
report is rejected outright — it must first be reopened. Requests without
the required permission return 403 Forbidden.
Daily reports are authored — and their status changed (submitted, approved, reopened) — in the Zeitstrom web and mobile apps. Through the API you can read reports and their entries, trigger the time-tracking autofill, download PDFs, and request photo upload tokens. Creating entries and changing a report's status are not currently available for API tokens.
The Report Object
A report is the group of all entries that share a project and a date.
Reports only exist for projects that have daily reports enabled in the
project's settings, and only for days that have at least one entry. The
tag_id is the project's id as returned by the
Projects API.
Every report has a computed status describing its position in the review lifecycle:
draft— the report is being worked on and can be edited on site.submitted— the site crew handed the report in for review. Only supervisors (users with the approve permission) may still change it.closed— the report was approved. Likesubmitted, it is locked for regular editors.archived— the report was archived by a supervisor. Archived reports are immutable (including the time-tracking autofill) until a supervisor moves them back todraft.
- Name
id- Type
- string
- Description
Synthetic identifier of the report in the form
<tag_id>|<date>, e.g.3f2b8c1e-9a47-4d05-b8a1-6c2d94e07f31|2024-06-18. Read-only.
- Name
date- Type
- string (YYYY-MM-DD)
- Description
The calendar day the report covers.
- Name
tag_id- Type
- string (UUID)
- Description
The project the report belongs to.
- Name
status- Type
- string
- Description
Computed report status:
draft,submitted,closed, orarchived.
- Name
tag- Type
- object or null
- Description
The project the report belongs to, as
{id, name, code, color}, ornullif the project could not be resolved. Only present in list responses. Read-only.
- Name
address- Type
- string
- Description
The project's configured address, or an empty string. Only present in list responses. Read-only.
- Name
cost_center- Type
- string
- Description
The project's configured cost center, or an empty string. Only present in list responses. Read-only.
- Name
client- Type
- string
- Description
The project's configured client, or an empty string. Only present in list responses. Read-only.
- Name
contributor_count- Type
- integer
- Description
Number of distinct users who authored an entry on this report. Only present in list responses. Read-only.
- Name
employees- Type
- array of objects
- Description
Employees with
employee-working-timesentries on this report, as{id, first_name, last_name}. Only present in list responses. Read-only.
- Name
total_hours- Type
- number
- Description
Sum of the
hoursvalue across the report'semployee-working-timesentries. Only present in list responses. Read-only.
- Name
weather- Type
- array of objects
- Description
The report's captured weather readings, sorted by
time. Each object has the same shape as theweatherentry value fields. Only present in list responses. Read-only.
- Name
values- Type
- array of objects
- Description
The report's newest visible value per field type (not per group), each carrying that field's type-specific value fields plus a
typekey. Lets an overview client render a report card without a follow-up request to the entries endpoint. Only present in list responses. Read-only.
Field Configurations
Which fields a daily report contains is configurable per organization, and
the configuration is versioned by date. Your organization keeps a list of
configurations, each with a valid_from date; the configuration that applies
to a report is the one with the most recent valid_from on or before the
report's date (a configuration becomes active on its valid_from day).
A report whose date lies before every stored valid_from uses your
organization's oldest configuration. The first version is written when
daily reports are switched on, so reports for days before that switch match
no version at all — they are rendered with the oldest field set your
organization ever had, not with the built-in default form. The default form
below applies only to organizations that have no configuration at all:
| Field id | Type | Label (German) |
|---|---|---|
weather | weather | Witterung |
employee-working-times | employee-working-times | Mitarbeitende |
subcontractors | subcontractors | Nachunternehmen |
activities | activities | Tätigkeiten |
materials | string | Material- / Geräteeinsatz |
comments | string | Bemerkungen / Behinderungen |
photos | image | Fotos |
signatures | signature | Unterschriften |
Versioning has two consequences you will notice in the API:
- Every entry is interpreted and validated against the configuration that is active on the entry's date, not the one active today. Historical reports keep the form they were written with, even after the organization changes its report layout.
- Entries whose field id does not exist in the configuration active for their date (for example, a field that was later removed) are omitted from entry listings and PDFs — they have no schema to render.
Use the field-types endpoint to discover the available field types and how entries of each type are grouped.
The Entry Object
Entries are append-only: nothing is ever updated in place. Each entry
belongs to a logical group identified by its group_id, which combines the
report's date and tag_id with type-specific keys (for example, one group
per employee for working times, or one group per author-and-text for
comments). The most recent entry of a group is its current value; older
entries are the group's history. An entry with burned: true is a tombstone
that marks its group as deleted.
Entries written by the system — the time-tracking autofill and the automatic
weather capture — have author_id: null; the affected employee is carried in
on_behalf_of_id. Manually authored entries carry the author, and
on_behalf_of_id names the person the entry is about (e.g. who signed, or
whose working time was corrected).
- Name
id- Type
- string (UUID)
- Description
Unique identifier of the entry. Read-only.
- Name
group_id- Type
- string
- Description
Pipe-separated grouping key, starting with
dateandtag_idfollowed by the field type's grouping values. Read-only.
- Name
group_count- Type
- integer
- Description
Number of entries in this entry's group that match the request's filters, including tombstones — filtering by
idsexcludes the group's other entries from the count. Only present in list responses. Read-only.
- Name
field_id- Type
- string
- Description
Id of the report field the entry belongs to, as defined in the active field configuration (e.g.
comments).
- Name
type- Type
- string
- Description
The field's type:
weather,employee-working-times,subcontractors,activities,string,image, orsignature.
- Name
date- Type
- string (YYYY-MM-DD)
- Description
The report day the entry belongs to.
- Name
tag_id- Type
- string (UUID)
- Description
The project the entry belongs to.
- Name
author_id- Type
- string (UUID) or null
- Description
The user who authored the entry, or
nullfor system-generated entries (autofill, weather capture).
- Name
author_name- Type
- string or null
- Description
Full name of the author, or
null.
- Name
on_behalf_of_id- Type
- string (UUID) or null
- Description
The user the entry is about (e.g. the employee whose hours are recorded, or the person who signed), or
null.
- Name
on_behalf_of_name- Type
- string or null
- Description
Full name of the
on_behalf_ofuser, ornull.
- Name
burned- Type
- boolean
- Description
truemarks the entry as a tombstone: the group it belongs to should be treated as deleted if the tombstone is the group's latest entry.
- Name
submitted_at- Type
- string (ISO 8601, local time) or null
- Description
When the entry reached the server, e.g.
2024-06-18T16:42:07.nullfor system-generated entries.
- Name
created_at- Type
- string (ISO 8601, local time)
- Description
When the entry was stored. Read-only.
- Name
modified_at- Type
- string (ISO 8601, local time)
- Description
When the entry was last modified. Read-only.
Type-specific value fields
In addition to the common properties above, each entry carries the value fields of its type:
-
weather—time(string, a clock time such as08:00),temperature(number ornull), andweather_condition: one ofsunny,cloudy,precipitationorsnow, ornullwhen the reading carries no usable condition. The four categories are the ones listed underchoices.conditionin the field types response. Grouped bytime, so a report holds one weather row per configured time slot.Writes may additionally carry
precipitationandcloud_cover(numbers) andwind(a[speed, direction]pair with the direction in degrees0–359). Those keys are still validated and stored, but reads no longer return them. Automatically captured readings are reduced the same way: the weather provider's detailed response stays server-side and is folded into the singleweather_conditioncategory. -
employee-working-times—hours(number between0and24), plus a snapshot of the employee at the time the entry was written:employee_account_id(string),employee_name(string), andemployee_position(string, from the employee'spositioncustom field; empty string if unset). The snapshot keeps the report accurate even if the employee's account or custom fields change later. Grouped byon_behalf_of_id: one row per employee and day. -
subcontractors—name(string),employees(integer),hours(number ornull),comment(string ornull). Grouped byon_behalf_of_idandname. -
activities—text(string). Grouped byon_behalf_of_idandtext, so the same activity text for the same person deduplicates. -
string—value(string). Used by the defaultmaterialsandcommentsfields. Grouped byon_behalf_of_idandvalue. -
image—image_id(string),image_key(string ornull, the S3 object key from the photo upload flow),image_url(string ornull— a pre-signed download URL derived fromimage_key, valid for one hour),thumb_key(string ornull, the object key of the downscaled preview),thumb_url(string ornull— a pre-signed download URL derived fromthumb_key, valid for one hour),latitude/longitude(numbers ornull), andtaken_at(string ornull). Grouped byon_behalf_of_idandimage_id.thumb_keyandthumb_urlarenullfor entries whose client did not upload a preview; fall back toimage_urlin that case. -
signature—image(string, adata:image/...data URL of the signature). Grouped byon_behalf_of_id: one signature per person per report.
List all Reports
Retrieve a paginated list of report descriptors, one per project and date that has at least one entry. Results are ordered by date descending, then by project id, and cover only projects that have daily reports enabled and that your token is allowed to see.
Query Parameters
- Name
date_from- Type
- string (YYYY-MM-DD)
- Description
Only include reports on or after this date. Invalid values are ignored.
- Name
date_to- Type
- string (YYYY-MM-DD)
- Description
Only include reports on or before this date. Invalid values are ignored.
- Name
daterange- Type
- string
- Description
Inclusive date range in the form
YYYY-MM-DD|YYYY-MM-DD, e.g.daterange=2024-06-17|2024-06-18. When given, it takes precedence overdate_from/date_to. Both dates are required; a malformed or half-open range returns an empty result.
- Name
projects- Type
- string
- Description
Restrict to specific projects by passing a pipe-separated list of project ids (UUIDs). Invalid UUIDs are dropped from the list; if no valid id remains, the result is empty.
- Name
status- Type
- string
- Description
Pipe-separated set of statuses to keep, e.g.
status=submitted|closed. Valid values aredraft,submitted,closed, andarchived; unknown values are ignored, and an empty filter returns all reports.
- Name
limit- Type
- integer
- Description
Number of results per page. Defaults to 100, maximum 1000.
- Name
offset- Type
- integer
- Description
Number of results to skip for pagination. Defaults to 0.
Request
curl -X GET "https://api.zeitstrom.com/api/v2/daily-reports/reports/?date_from=2024-06-17&date_to=2024-06-18&status=draft|submitted" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Response
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"id": "3f2b8c1e-9a47-4d05-b8a1-6c2d94e07f31|2024-06-18",
"date": "2024-06-18",
"tag_id": "3f2b8c1e-9a47-4d05-b8a1-6c2d94e07f31",
"status": "submitted",
"tag": {
"id": "3f2b8c1e-9a47-4d05-b8a1-6c2d94e07f31",
"name": "Neubau Lagerhalle",
"code": "P-2024-018",
"color": "#2563eb"
},
"address": "Industriestraße 12, 44269 Dortmund",
"cost_center": "4711",
"client": "Musterbau GmbH",
"contributor_count": 2,
"employees": [
{ "id": "508d5250-7399-4b65-a574-3da53d9ddc25", "first_name": "Anna", "last_name": "Schmidt" }
],
"total_hours": 7.75,
"weather": [
{ "time": "08:00", "temperature": 14.2, "weather_condition": "cloudy" }
],
"values": [
{
"type": "weather",
"time": "08:00",
"temperature": 14.2,
"weather_condition": "cloudy"
},
{
"type": "employee-working-times",
"on_behalf_of_id": "508d5250-7399-4b65-a574-3da53d9ddc25",
"on_behalf_of_name": "Anna Schmidt",
"hours": 7.75
}
]
},
{
"id": "3f2b8c1e-9a47-4d05-b8a1-6c2d94e07f31|2024-06-17",
"date": "2024-06-17",
"tag_id": "3f2b8c1e-9a47-4d05-b8a1-6c2d94e07f31",
"status": "draft",
"tag": {
"id": "3f2b8c1e-9a47-4d05-b8a1-6c2d94e07f31",
"name": "Neubau Lagerhalle",
"code": "P-2024-018",
"color": "#2563eb"
},
"address": "Industriestraße 12, 44269 Dortmund",
"cost_center": "4711",
"client": "Musterbau GmbH",
"contributor_count": 0,
"employees": [],
"total_hours": 0,
"weather": [],
"values": []
}
]
}
List Field Types
Retrieve the available field types, the keys entries of each type are
grouped by, and a human-readable description of what the type is for. Every
group_by list starts with the common date and tag_id keys, followed by
the type's own grouping values.
Each type also carries choices, an object of named choice lists for the
value fields that accept a fixed set of values. Every list holds
{id, label} objects, where id is what entries store and label is the
German text to show. Types without such a field return an empty object, so
clients can read the picker options from the server instead of hard-coding
them. Today only weather defines choices, under the key condition.
Request
curl -X GET "https://api.zeitstrom.com/api/v2/daily-reports/reports/field-types/" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Response
{
"count": 7,
"next": null,
"previous": null,
"results": [
{
"id": "weather",
"group_by": ["date", "tag_id", "time"],
"description": "Weather readings for configured local report times.\n\nConfig: requires `times`, a list of HHMM strings such as `[\"0800\"]`, and\n`autofill_from_api`, a boolean that controls weather autofill from an API.",
"choices": {
"condition": [
{ "id": "sunny", "label": "Sonnig" },
{ "id": "cloudy", "label": "Bewölkt" },
{ "id": "precipitation", "label": "Niederschlag" },
{ "id": "snow", "label": "Schnee" }
]
}
},
{
"id": "employee-working-times",
"group_by": ["date", "tag_id", "on_behalf_of_id"],
"description": "Working-time totals for employees contributing to a daily report.\n\nConfig: requires `autofill_from_tracking`, a boolean that controls whether\ntracked working times are imported automatically.",
"choices": {}
},
{
"id": "subcontractors",
"group_by": ["date", "tag_id", "on_behalf_of_id", "name"],
"description": "Per-day list of subcontractor companies present on a project.\n\nConfig: no options are supported; pass `{}` or omit the config.\nValues require `name` and `employees`; `hours` and `comment` are optional.",
"choices": {}
},
{
"id": "activities",
"group_by": ["date", "tag_id", "on_behalf_of_id", "text"],
"description": "Activity notes for work performed on a daily report.\n\nConfig: requires `autofill_from_tracking`, a boolean that controls whether\ntime-tracking comments are imported automatically.",
"choices": {}
},
{
"id": "string",
"group_by": ["date", "tag_id", "on_behalf_of_id", "value"],
"description": "Free-text report entry used for configurable text fields.\n\nConfig: no options are supported; pass `{}` or omit the config.",
"choices": {}
},
{
"id": "image",
"group_by": ["date", "tag_id", "on_behalf_of_id", "image_id"],
"description": "Photo attachment for a daily report, including optional capture metadata.\n\nConfig: no options are supported; pass `{}` or omit the config.",
"choices": {}
},
{
"id": "signature",
"group_by": ["date", "tag_id", "on_behalf_of_id"],
"description": "Signature image captured for a report participant.\n\nConfig: no options are supported; pass `{}` or omit the config.",
"choices": {}
}
]
}
Retrieve Report Status
Get the current status of a single report. A report without any recorded
status transition is a draft.
Query Parameters
- Name
tag- Type
- string (UUID)
- Description
The project id. Required. An unknown or inaccessible project returns a
400validation error.
- Name
date- Type
- string (YYYY-MM-DD)
- Description
The report date. Required.
Request
curl -X GET "https://api.zeitstrom.com/api/v2/daily-reports/reports/status/?tag=3f2b8c1e-9a47-4d05-b8a1-6c2d94e07f31&date=2024-06-18" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Response
{
"tag_id": "3f2b8c1e-9a47-4d05-b8a1-6c2d94e07f31",
"date": "2024-06-18",
"status": "submitted"
}
Autofill a Report
Compute and store report entries from the day's time tracking on the
project. Only fields whose active configuration carries
autofill_from_tracking and whose type is employee-working-times or
activities are filled — with the default configuration these
are employee-working-times (each employee's tracked hours on the project,
rounded to two decimals) and activities (one entry per distinct tracking
comment and employee).
The operation creates entries as a side effect. System-written entries
have author_id: null. The autofill is idempotent: repeated calls converge
to the same state, unchanged values are skipped, and a value that was
manually corrected by a user is never overwritten.
Autofilling a report that is submitted or closed requires the
daily_reports:approve permission; without it the request returns
403 Forbidden.
- Name
tag- Type
- string (UUID)
- Description
The project id. Required. An unknown or inaccessible project returns a
400validation error.
- Name
date- Type
- string (YYYY-MM-DD)
- Description
The report date. Required.
- Name
field- Type
- string
- Description
Optional field id to restrict the autofill to a single field, e.g.
activities. A field that is not autofillable results infilled: [].
Request
curl -X POST "https://api.zeitstrom.com/api/v2/daily-reports/reports/autofill/" \
-H "Authorization: Token <YOUR_API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"tag": "3f2b8c1e-9a47-4d05-b8a1-6c2d94e07f31",
"date": "2024-06-18"
}'
Response
{
"tag_id": "3f2b8c1e-9a47-4d05-b8a1-6c2d94e07f31",
"date": "2024-06-18",
"filled": ["employee-working-times", "activities"]
}
Download a Report PDF
Render a single report as a print-friendly PDF. The response streams the PDF
binary (Content-Type: application/pdf) with a filename of the form
Tagesbericht-<project code>-<date>.pdf. The PDF contains the fields of the
configuration active for the report's date, with the report's status shown
in the header.
The id is the report's synthetic identifier <tag_id>|<date> as returned by
List all Reports. The | may be sent literally or
percent-encoded as %7C. An id without a date part, a date that is not a
valid YYYY-MM-DD, or a project that is unknown, disabled or outside your
visible set all return a 400 validation error.
This endpoint previously took the report as ?tag=<id>&date=<date> query
parameters on /api/v2/daily-reports/reports/pdf/. That form has been
removed — pass the report id in the path instead.
Request
curl -X GET "https://api.zeitstrom.com/api/v2/daily-reports/reports/3f2b8c1e-9a47-4d05-b8a1-6c2d94e07f31%7C2024-06-18/pdf/" \
-H "Authorization: Token <YOUR_API_TOKEN>" \
-o "Tagesbericht-2024-06-18.pdf"
List all Entries
Retrieve a paginated list of report entries, projected through the field
configuration active for each entry's date. Entries of fields that no longer
exist in the active configuration are omitted. To reconstruct the current
content of a report, request grouped=1 for a single project and date and
treat groups whose latest entry is burned: true as deleted.
Query Parameters
- Name
tags- Type
- string
- Description
Restrict to specific projects by passing a pipe-separated list of project ids (UUIDs). If any id is invalid or refers to a project you cannot see, the result is empty.
- Name
field_id- Type
- string
- Description
Restrict to entries of one configured field id, e.g.
field_id=comments.
- Name
daterange- Type
- string
- Description
Inclusive date range in the form
YYYY-MM-DD|YYYY-MM-DD, e.g.daterange=2024-06-18|2024-06-18. Both dates are required; a malformed or half-open range yields an empty result.
- Name
grouped- Type
- string
- Description
Set
grouped=1to return only the most recent entry per group. The returnedgroup_countstill reflects the full group size.
- Name
ids- Type
- string
- Description
Restrict to specific entries by passing a pipe-separated list of entry ids (UUIDs). Invalid UUIDs are dropped from the list; if no valid id remains, the result is empty.
- Name
limit- Type
- integer
- Description
Number of results per page. Defaults to 100, maximum 1000.
- Name
offset- Type
- integer
- Description
Number of results to skip for pagination. Defaults to 0.
Request
curl -X GET "https://api.zeitstrom.com/api/v2/daily-reports/entries/?tags=3f2b8c1e-9a47-4d05-b8a1-6c2d94e07f31&daterange=2024-06-18|2024-06-18&grouped=1" \
-H "Authorization: Token <YOUR_API_TOKEN>"
Response
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"group_id": "2024-06-18|3f2b8c1e-9a47-4d05-b8a1-6c2d94e07f31|508d5250-7399-4b65-a574-3da53d9ddc25",
"id": "6b0f2d84-3c9e-4f17-8a52-b1d4e7c90a63",
"field_id": "employee-working-times",
"type": "employee-working-times",
"created_at": "2024-06-18T17:02:11",
"modified_at": "2024-06-18T17:02:11",
"submitted_at": null,
"date": "2024-06-18",
"tag_id": "3f2b8c1e-9a47-4d05-b8a1-6c2d94e07f31",
"author_id": null,
"on_behalf_of_id": "508d5250-7399-4b65-a574-3da53d9ddc25",
"author_name": null,
"on_behalf_of_name": "Anna Schmidt",
"burned": false,
"hours": 7.75,
"group_count": 1
},
{
"group_id": "2024-06-18|3f2b8c1e-9a47-4d05-b8a1-6c2d94e07f31|e7c9a4d2-1f38-4b6a-9c05-8d2f7b3e6a14|Lieferung Schalholz verspätet",
"id": "9d47c1f0-5e2b-4a86-b3f9-0c61d8a24e57",
"field_id": "comments",
"type": "string",
"created_at": "2024-06-18T16:42:09",
"modified_at": "2024-06-18T16:42:09",
"submitted_at": "2024-06-18T16:42:07",
"date": "2024-06-18",
"tag_id": "3f2b8c1e-9a47-4d05-b8a1-6c2d94e07f31",
"author_id": "e7c9a4d2-1f38-4b6a-9c05-8d2f7b3e6a14",
"on_behalf_of_id": "e7c9a4d2-1f38-4b6a-9c05-8d2f7b3e6a14",
"author_name": "Jonas Weber",
"on_behalf_of_name": "Jonas Weber",
"burned": false,
"value": "Lieferung Schalholz verspätet",
"group_count": 1
}
]
}
Get a Photo Upload Token
Generate a pre-signed upload token for a daily-report photo (at most 2 MB).
Photos are capped well below the 15 MB allowed for document attachments
elsewhere in the API, because they are rendered into the PDF export —
downscale on the client before uploading.
The response contains a pre-signed S3 url and form fields, valid for 12
hours. Upload the photo as a multipart/form-data POST to url, including
all fields plus the file itself. The returned fields.key is the object
key that photo entries store as their image_key; when entries are read,
the server signs it back into a temporary image_url download link. Both
image_key and thumb_key are validated to lie inside your organization's
upload namespace — scoped to the authenticated user rather than a specific
employee — before an entry is persisted; a key pointing anywhere else is
rejected.
The response also contains thumb_fields, a second set of signed form fields
for uploading a downscaled preview alongside the original. Both tokens POST to
the same url and share the same bucket, size limit and 12-hour lifetime —
only the signed fields differ. thumb_fields.key is fields.key with a
.thumb infix before the extension (…/photo.jpg →
…/photo.thumb.jpg), so either key can be derived from the other. Uploading
the preview is optional. When you do upload one, persist thumb_fields.key
on the photo entry as thumb_key alongside image_key: reads then sign it
into a thumb_url download link of its own, so clients can show the preview
without fetching the full-size original. Entries that carry no thumb_key
return null for both thumb_key and thumb_url.
- Name
filename- Type
- string
- Description
Name of the file, used as part of the storage key.
- Name
filetype- Type
- string
- Description
MIME type of the file (e.g.
image/jpeg), used to derive the file extension.
- Name
filesize- Type
- integer
- Description
Size of the file in bytes. Requests above 2097152 bytes (2 MB) are rejected.
Request
curl -X POST "https://api.zeitstrom.com/api/v2/daily-reports/entries/upload-photo-token/" \
-H "Authorization: Token <YOUR_API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"filename": "betonage-nord",
"filetype": "image/jpeg",
"filesize": 2048576
}'
Response
{
"url": "https://s3.eu-central-1.amazonaws.com/zeitstrom-uploads",
"fields": {
"key": "i-f4a5b6c7-d8e9-0123-fabc-456789012345/u-a1b2c3d4-e5f6-7890-abcd-ef1234567890/daily-reports/2024/06/18/0d3e2b1a-4c5d-6e7f-8901-234567890abc/2024-06-18_4f2a_betonage-nord.jpg",
"AWSAccessKeyId": "AKIAIOSFODNN7EXAMPLE",
"policy": "eyJleHBpcmF0aW9uIjogIjIwMjQtMDYtMTlUMDY6MzA6MDBaIiwgImNvbmRpdGlvbnMiOiBbXX0=",
"signature": "hV0kwGx0ZQKgQnJ1zW0m9dEXAMPLE"
},
"thumb_fields": {
"key": "i-f4a5b6c7-d8e9-0123-fabc-456789012345/u-a1b2c3d4-e5f6-7890-abcd-ef1234567890/daily-reports/2024/06/18/0d3e2b1a-4c5d-6e7f-8901-234567890abc/2024-06-18_4f2a_betonage-nord.thumb.jpg",
"AWSAccessKeyId": "AKIAIOSFODNN7EXAMPLE",
"policy": "eyJleHBpcmF0aW9uIjogIjIwMjQtMDYtMTlUMDY6MzA6MDBaIiwgImNvbmRpdGlvbnMiOiBbXX0=",
"signature": "yQ2mNpR7bTfLc0aVzX4jE9EXAMPLE"
}
}