@gruncellka/porto-data 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/CHANGELOG.md +215 -0
  2. package/LICENSE +199 -5
  3. package/README.md +53 -34
  4. package/index.d.ts +35 -18
  5. package/index.js +2 -1
  6. package/package.json +28 -8
  7. package/porto_data/formats/envelopes.json +120 -0
  8. package/porto_data/formats/layouts.json +288 -0
  9. package/porto_data/mappings.json +65 -10
  10. package/porto_data/metadata.json +662 -125
  11. package/porto_data/policy/jurisdictions.json +839 -0
  12. package/porto_data/policy/markets.json +75 -0
  13. package/porto_data/policy/restrictions.json +668 -0
  14. package/porto_data/providers/deutschepost/features.json +42 -0
  15. package/porto_data/providers/deutschepost/graph.json +203 -0
  16. package/porto_data/providers/deutschepost/limits.json +17 -0
  17. package/porto_data/providers/deutschepost/marks.json +71 -0
  18. package/porto_data/providers/deutschepost/prices/products.json +239 -0
  19. package/porto_data/providers/deutschepost/prices/services.json +51 -0
  20. package/porto_data/providers/deutschepost/products.json +197 -0
  21. package/porto_data/providers/deutschepost/services.json +88 -0
  22. package/porto_data/providers/deutschepost/weights.json +46 -0
  23. package/porto_data/providers/deutschepost/zones.json +231 -0
  24. package/porto_data/providers/laposte/features.json +42 -0
  25. package/porto_data/providers/laposte/graph.json +234 -0
  26. package/porto_data/providers/laposte/limits.json +17 -0
  27. package/porto_data/providers/laposte/marks.json +39 -0
  28. package/porto_data/providers/laposte/prices/products.json +947 -0
  29. package/porto_data/providers/laposte/prices/services.json +41 -0
  30. package/porto_data/providers/laposte/products.json +276 -0
  31. package/porto_data/providers/laposte/services.json +63 -0
  32. package/porto_data/providers/laposte/weights.json +38 -0
  33. package/porto_data/providers/laposte/zones.json +230 -0
  34. package/porto_data/providers/swisspost/features.json +21 -0
  35. package/porto_data/providers/swisspost/graph.json +212 -0
  36. package/porto_data/providers/swisspost/limits.json +17 -0
  37. package/porto_data/providers/swisspost/marks.json +41 -0
  38. package/porto_data/providers/swisspost/prices/products.json +347 -0
  39. package/porto_data/providers/swisspost/prices/services.json +31 -0
  40. package/porto_data/providers/swisspost/products.json +193 -0
  41. package/porto_data/providers/swisspost/rules.json +25 -0
  42. package/porto_data/providers/swisspost/services.json +40 -0
  43. package/porto_data/providers/swisspost/weights.json +38 -0
  44. package/porto_data/providers/swisspost/zones.json +223 -0
  45. package/porto_data/providers/ukrposhta/features.json +28 -0
  46. package/porto_data/providers/ukrposhta/graph.json +148 -0
  47. package/porto_data/providers/ukrposhta/limits.json +17 -0
  48. package/porto_data/providers/ukrposhta/marks.json +25 -0
  49. package/porto_data/providers/ukrposhta/prices/products.json +123 -0
  50. package/porto_data/providers/ukrposhta/prices/services.json +42 -0
  51. package/porto_data/providers/ukrposhta/products.json +74 -0
  52. package/porto_data/providers/ukrposhta/services.json +40 -0
  53. package/porto_data/providers/ukrposhta/weights.json +26 -0
  54. package/porto_data/providers/ukrposhta/zones.json +226 -0
  55. package/porto_data/providers.json +37 -0
  56. package/porto_data/schemas/envelopes.schema.json +120 -0
  57. package/porto_data/schemas/features.schema.json +66 -55
  58. package/porto_data/schemas/graph.schema.json +189 -0
  59. package/porto_data/schemas/jurisdictions.schema.json +116 -0
  60. package/porto_data/schemas/layouts.schema.json +156 -0
  61. package/porto_data/schemas/limits.schema.json +253 -0
  62. package/porto_data/schemas/mappings.schema.json +73 -0
  63. package/porto_data/schemas/markets.schema.json +186 -0
  64. package/porto_data/schemas/marks.schema.json +127 -0
  65. package/porto_data/schemas/metadata.schema.json +183 -0
  66. package/porto_data/schemas/porto_ids.schema.json +45 -0
  67. package/porto_data/schemas/product_prices.schema.json +126 -0
  68. package/porto_data/schemas/products.schema.json +338 -110
  69. package/porto_data/schemas/providers.schema.json +71 -0
  70. package/porto_data/schemas/restrictions.schema.json +175 -355
  71. package/porto_data/schemas/rules.schema.json +104 -0
  72. package/porto_data/schemas/service_prices.schema.json +116 -0
  73. package/porto_data/schemas/services.schema.json +113 -70
  74. package/porto_data/schemas/weights.schema.json +70 -0
  75. package/porto_data/schemas/zones.schema.json +78 -72
  76. package/porto_data/data/data_links.json +0 -148
  77. package/porto_data/data/dimensions.json +0 -158
  78. package/porto_data/data/features.json +0 -66
  79. package/porto_data/data/prices.json +0 -242
  80. package/porto_data/data/products.json +0 -84
  81. package/porto_data/data/restrictions.json +0 -795
  82. package/porto_data/data/services.json +0 -61
  83. package/porto_data/data/weight_tiers.json +0 -54
  84. package/porto_data/data/zones.json +0 -230
  85. package/porto_data/schemas/data_links.schema.json +0 -223
  86. package/porto_data/schemas/dimensions.schema.json +0 -215
  87. package/porto_data/schemas/prices.schema.json +0 -180
  88. package/porto_data/schemas/weight_tiers.schema.json +0 -70
@@ -0,0 +1,212 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/gruncellka/porto-data/refs/heads/main/porto_data/schemas/graph.schema.json",
3
+ "file_type": "graph",
4
+ "provider": "swisspost",
5
+ "unit": {
6
+ "weight": "g",
7
+ "dimension": "mm",
8
+ "price": "cents",
9
+ "currency": "CHF"
10
+ },
11
+ "dependencies": {
12
+ "products": {
13
+ "file": "products.json",
14
+ "depends_on": [
15
+ "zones.json",
16
+ "weights.json",
17
+ "formats/envelopes.json",
18
+ "services.json",
19
+ "features.json",
20
+ "marks.json"
21
+ ],
22
+ "description": "Products require zones, weight tiers, canonical envelope format ids, services, features, and mark profiles"
23
+ },
24
+ "services": {
25
+ "file": "services.json",
26
+ "depends_on": [
27
+ "features.json"
28
+ ],
29
+ "description": "Services require features"
30
+ },
31
+ "product_prices": {
32
+ "file": "prices/products.json",
33
+ "depends_on": [
34
+ "products.json",
35
+ "zones.json",
36
+ "weights.json"
37
+ ],
38
+ "description": "Base postage grid; file providers/<id>/prices/products.json (file_type product_prices)"
39
+ },
40
+ "service_prices": {
41
+ "file": "prices/services.json",
42
+ "depends_on": [
43
+ "products.json",
44
+ "services.json",
45
+ "zones.json",
46
+ "weights.json"
47
+ ],
48
+ "description": "Service surcharge amounts; file providers/<id>/prices/services.json (file_type service_prices)"
49
+ },
50
+ "zones": {
51
+ "file": "zones.json",
52
+ "depends_on": [
53
+ "policy/restrictions.json"
54
+ ],
55
+ "description": "Zones may have restricted destinations"
56
+ },
57
+ "weights": {
58
+ "file": "weights.json",
59
+ "depends_on": [],
60
+ "description": "Weight brackets (tier ids) are standalone definitions"
61
+ },
62
+ "envelopes": {
63
+ "file": "formats/envelopes.json",
64
+ "depends_on": [],
65
+ "description": "Global envelope id catalog: physical front size (mm); international baseline (e.g. ISO 269); file formats/envelopes.json"
66
+ },
67
+ "envelope_layouts": {
68
+ "file": "formats/layouts.json",
69
+ "depends_on": [
70
+ "formats/envelopes.json"
71
+ ],
72
+ "description": "Jurisdiction-keyed print/window layout (DE/CH/FR); file formats/layouts.json"
73
+ },
74
+ "jurisdictions": {
75
+ "file": "policy/jurisdictions.json",
76
+ "depends_on": [],
77
+ "description": "UN/EU membership sets for restriction framework jurisdiction resolution"
78
+ },
79
+ "markets": {
80
+ "file": "policy/markets.json",
81
+ "depends_on": [],
82
+ "description": "Country-level currency, VAT, and international quote currencies for providers.json country"
83
+ },
84
+ "restrictions": {
85
+ "file": "policy/restrictions.json",
86
+ "depends_on": [
87
+ "policy/jurisdictions.json",
88
+ "zones.json",
89
+ "products.json"
90
+ ],
91
+ "description": "Global destination restrictions (bundled as policy/restrictions.json); optional cross-reference to zones and products"
92
+ },
93
+ "limits": {
94
+ "file": "limits.json",
95
+ "depends_on": [
96
+ "policy/restrictions.json"
97
+ ],
98
+ "description": "Provider operational limits extend global restrictions after load"
99
+ },
100
+ "features": {
101
+ "file": "features.json",
102
+ "depends_on": [],
103
+ "description": "Features are standalone"
104
+ },
105
+ "marks": {
106
+ "file": "marks.json",
107
+ "depends_on": [],
108
+ "description": "Franking profile catalog: profiles[] (sizes); resolution in graph.edges.marks"
109
+ },
110
+ "rules": {
111
+ "file": "rules.json",
112
+ "depends_on": [
113
+ "graph.json",
114
+ "products.json",
115
+ "services.json",
116
+ "zones.json",
117
+ "prices/services.json"
118
+ ],
119
+ "description": "Conditional letter policies (e.g. thickness surcharge); SDK evaluates after base resolution"
120
+ }
121
+ },
122
+ "services": [
123
+ "a_mail_plus"
124
+ ],
125
+ "edges": {
126
+ "products": {
127
+ "a_post_standardbrief": {
128
+ "zones": [
129
+ "domestic"
130
+ ],
131
+ "weight_tiers": [
132
+ "W0020",
133
+ "W0050",
134
+ "W0100"
135
+ ]
136
+ },
137
+ "a_post_grossbrief": {
138
+ "zones": [
139
+ "domestic"
140
+ ],
141
+ "weight_tiers": [
142
+ "W0250",
143
+ "W0500",
144
+ "W1000"
145
+ ]
146
+ },
147
+ "b_post_standardbrief": {
148
+ "zones": [
149
+ "domestic"
150
+ ],
151
+ "weight_tiers": [
152
+ "W0020",
153
+ "W0050",
154
+ "W0100"
155
+ ]
156
+ },
157
+ "b_post_grossbrief": {
158
+ "zones": [
159
+ "domestic"
160
+ ],
161
+ "weight_tiers": [
162
+ "W0250",
163
+ "W0500",
164
+ "W1000"
165
+ ]
166
+ },
167
+ "international_standardbrief": {
168
+ "zones": [
169
+ "zone_1_eu",
170
+ "world"
171
+ ],
172
+ "weight_tiers": [
173
+ "W0020",
174
+ "W0050",
175
+ "W0100"
176
+ ]
177
+ },
178
+ "international_grossbrief": {
179
+ "zones": [
180
+ "zone_1_eu",
181
+ "world"
182
+ ],
183
+ "weight_tiers": [
184
+ "W0250",
185
+ "W0500"
186
+ ]
187
+ },
188
+ "international_maxibrief": {
189
+ "zones": [
190
+ "zone_1_eu",
191
+ "world"
192
+ ],
193
+ "weight_tiers": [
194
+ "W0500",
195
+ "W1000",
196
+ "W2000"
197
+ ]
198
+ }
199
+ },
200
+ "marks": {
201
+ "domestic": {
202
+ "profile": "domestic"
203
+ },
204
+ "zone_1_eu": {
205
+ "profile": "international"
206
+ },
207
+ "world": {
208
+ "profile": "international"
209
+ }
210
+ }
211
+ }
212
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/gruncellka/porto-data/refs/heads/main/porto_data/schemas/limits.schema.json",
3
+ "file_type": "limits",
4
+ "provider": "swisspost",
5
+ "unit": {
6
+ "country_code": "ISO 3166-1 alpha-2",
7
+ "date": "ISO 8601"
8
+ },
9
+ "context": {
10
+ "national": {
11
+ "description": "Letter-format products only. Letter destination gating: policy/restrictions.json + zones.json. Switzerland is not in the EU; CH is domestic when posting from CH. limits[] only for Swiss Post–documented letter operational blocks.",
12
+ "notes": "Keep limits[] minimal; add a row only when Post CH materially restricts or suspends letters to a destination (verifiable). No parcel-only or generic geopolitical inventories."
13
+ }
14
+ },
15
+ "limits": [],
16
+ "frameworks": {}
17
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/gruncellka/porto-data/refs/heads/main/porto_data/schemas/marks.schema.json",
3
+ "file_type": "marks",
4
+ "provider": "swisspost",
5
+ "unit": {
6
+ "dimension": "mm"
7
+ },
8
+ "default_profile": "domestic",
9
+ "profiles": [
10
+ {
11
+ "id": "domestic",
12
+ "mark_type": "stamp",
13
+ "label": "WebStamp domestic",
14
+ "description": "Domestic WebStamp franking graphic",
15
+ "scope_notes": "Nominal footprint; registered WebStamp uses same size as domestic until measured separately",
16
+ "size": {
17
+ "width": 40,
18
+ "height": 40
19
+ },
20
+ "mime_type": [
21
+ "application/pdf",
22
+ "image/png"
23
+ ]
24
+ },
25
+ {
26
+ "id": "international",
27
+ "mark_type": "stamp",
28
+ "label": "WebStamp international",
29
+ "description": "International WebStamp franking graphic",
30
+ "scope_notes": "Same as domestic; registered WebStamp uses same size until measured separately",
31
+ "size": {
32
+ "width": 40,
33
+ "height": 40
34
+ },
35
+ "mime_type": [
36
+ "application/pdf",
37
+ "image/png"
38
+ ]
39
+ }
40
+ ]
41
+ }
@@ -0,0 +1,347 @@
1
+ {
2
+ "provider": "swisspost",
3
+ "unit": {
4
+ "price": "cents",
5
+ "currency": "CHF"
6
+ },
7
+ "$schema": "https://raw.githubusercontent.com/gruncellka/porto-data/refs/heads/main/porto_data/schemas/product_prices.schema.json",
8
+ "file_type": "product_prices",
9
+ "product_prices": [
10
+ {
11
+ "product_id": "a_post_standardbrief",
12
+ "zone": "domestic",
13
+ "weight_tier": "W0020",
14
+ "price": [
15
+ {
16
+ "amount": 120,
17
+ "effective_from": "2026-01-01",
18
+ "effective_to": null
19
+ }
20
+ ]
21
+ },
22
+ {
23
+ "product_id": "a_post_standardbrief",
24
+ "zone": "domestic",
25
+ "weight_tier": "W0050",
26
+ "price": [
27
+ {
28
+ "amount": 120,
29
+ "effective_from": "2026-01-01",
30
+ "effective_to": null
31
+ }
32
+ ]
33
+ },
34
+ {
35
+ "product_id": "a_post_standardbrief",
36
+ "zone": "domestic",
37
+ "weight_tier": "W0100",
38
+ "price": [
39
+ {
40
+ "amount": 120,
41
+ "effective_from": "2026-01-01",
42
+ "effective_to": null
43
+ }
44
+ ]
45
+ },
46
+ {
47
+ "product_id": "a_post_grossbrief",
48
+ "zone": "domestic",
49
+ "weight_tier": "W0250",
50
+ "price": [
51
+ {
52
+ "amount": 250,
53
+ "effective_from": "2026-01-01",
54
+ "effective_to": null
55
+ }
56
+ ]
57
+ },
58
+ {
59
+ "product_id": "a_post_grossbrief",
60
+ "zone": "domestic",
61
+ "weight_tier": "W0500",
62
+ "price": [
63
+ {
64
+ "amount": 250,
65
+ "effective_from": "2026-01-01",
66
+ "effective_to": null
67
+ }
68
+ ]
69
+ },
70
+ {
71
+ "product_id": "a_post_grossbrief",
72
+ "zone": "domestic",
73
+ "weight_tier": "W1000",
74
+ "price": [
75
+ {
76
+ "amount": 250,
77
+ "effective_from": "2026-01-01",
78
+ "effective_to": null
79
+ }
80
+ ]
81
+ },
82
+ {
83
+ "product_id": "b_post_standardbrief",
84
+ "zone": "domestic",
85
+ "weight_tier": "W0020",
86
+ "price": [
87
+ {
88
+ "amount": 100,
89
+ "effective_from": "2026-01-01",
90
+ "effective_to": null
91
+ }
92
+ ]
93
+ },
94
+ {
95
+ "product_id": "b_post_standardbrief",
96
+ "zone": "domestic",
97
+ "weight_tier": "W0050",
98
+ "price": [
99
+ {
100
+ "amount": 100,
101
+ "effective_from": "2026-01-01",
102
+ "effective_to": null
103
+ }
104
+ ]
105
+ },
106
+ {
107
+ "product_id": "b_post_standardbrief",
108
+ "zone": "domestic",
109
+ "weight_tier": "W0100",
110
+ "price": [
111
+ {
112
+ "amount": 100,
113
+ "effective_from": "2026-01-01",
114
+ "effective_to": null
115
+ }
116
+ ]
117
+ },
118
+ {
119
+ "product_id": "b_post_grossbrief",
120
+ "zone": "domestic",
121
+ "weight_tier": "W0250",
122
+ "price": [
123
+ {
124
+ "amount": 200,
125
+ "effective_from": "2026-01-01",
126
+ "effective_to": null
127
+ }
128
+ ]
129
+ },
130
+ {
131
+ "product_id": "b_post_grossbrief",
132
+ "zone": "domestic",
133
+ "weight_tier": "W0500",
134
+ "price": [
135
+ {
136
+ "amount": 200,
137
+ "effective_from": "2026-01-01",
138
+ "effective_to": null
139
+ }
140
+ ]
141
+ },
142
+ {
143
+ "product_id": "b_post_grossbrief",
144
+ "zone": "domestic",
145
+ "weight_tier": "W1000",
146
+ "price": [
147
+ {
148
+ "amount": 200,
149
+ "effective_from": "2026-01-01",
150
+ "effective_to": null
151
+ }
152
+ ]
153
+ },
154
+ {
155
+ "product_id": "international_standardbrief",
156
+ "zone": "zone_1_eu",
157
+ "weight_tier": "W0020",
158
+ "price": [
159
+ {
160
+ "amount": 190,
161
+ "effective_from": "2026-01-01",
162
+ "effective_to": null
163
+ }
164
+ ]
165
+ },
166
+ {
167
+ "product_id": "international_standardbrief",
168
+ "zone": "world",
169
+ "weight_tier": "W0020",
170
+ "price": [
171
+ {
172
+ "amount": 190,
173
+ "effective_from": "2026-01-01",
174
+ "effective_to": null
175
+ }
176
+ ]
177
+ },
178
+ {
179
+ "product_id": "international_standardbrief",
180
+ "zone": "zone_1_eu",
181
+ "weight_tier": "W0050",
182
+ "price": [
183
+ {
184
+ "amount": 310,
185
+ "effective_from": "2026-01-01",
186
+ "effective_to": null
187
+ }
188
+ ]
189
+ },
190
+ {
191
+ "product_id": "international_standardbrief",
192
+ "zone": "world",
193
+ "weight_tier": "W0050",
194
+ "price": [
195
+ {
196
+ "amount": 310,
197
+ "effective_from": "2026-01-01",
198
+ "effective_to": null
199
+ }
200
+ ]
201
+ },
202
+ {
203
+ "product_id": "international_standardbrief",
204
+ "zone": "zone_1_eu",
205
+ "weight_tier": "W0100",
206
+ "price": [
207
+ {
208
+ "amount": 430,
209
+ "effective_from": "2026-01-01",
210
+ "effective_to": null
211
+ }
212
+ ]
213
+ },
214
+ {
215
+ "product_id": "international_standardbrief",
216
+ "zone": "world",
217
+ "weight_tier": "W0100",
218
+ "price": [
219
+ {
220
+ "amount": 430,
221
+ "effective_from": "2026-01-01",
222
+ "effective_to": null
223
+ }
224
+ ]
225
+ },
226
+ {
227
+ "product_id": "international_grossbrief",
228
+ "zone": "zone_1_eu",
229
+ "weight_tier": "W0250",
230
+ "price": [
231
+ {
232
+ "amount": 750,
233
+ "effective_from": "2026-01-01",
234
+ "effective_to": null
235
+ }
236
+ ]
237
+ },
238
+ {
239
+ "product_id": "international_grossbrief",
240
+ "zone": "world",
241
+ "weight_tier": "W0250",
242
+ "price": [
243
+ {
244
+ "amount": 750,
245
+ "effective_from": "2026-01-01",
246
+ "effective_to": null
247
+ }
248
+ ]
249
+ },
250
+ {
251
+ "product_id": "international_grossbrief",
252
+ "zone": "zone_1_eu",
253
+ "weight_tier": "W0500",
254
+ "price": [
255
+ {
256
+ "amount": 1200,
257
+ "effective_from": "2026-01-01",
258
+ "effective_to": null
259
+ }
260
+ ]
261
+ },
262
+ {
263
+ "product_id": "international_grossbrief",
264
+ "zone": "world",
265
+ "weight_tier": "W0500",
266
+ "price": [
267
+ {
268
+ "amount": 1200,
269
+ "effective_from": "2026-01-01",
270
+ "effective_to": null
271
+ }
272
+ ]
273
+ },
274
+ {
275
+ "product_id": "international_maxibrief",
276
+ "zone": "zone_1_eu",
277
+ "weight_tier": "W0500",
278
+ "price": [
279
+ {
280
+ "amount": 1300,
281
+ "effective_from": "2026-01-01",
282
+ "effective_to": null
283
+ }
284
+ ]
285
+ },
286
+ {
287
+ "product_id": "international_maxibrief",
288
+ "zone": "world",
289
+ "weight_tier": "W0500",
290
+ "price": [
291
+ {
292
+ "amount": 1300,
293
+ "effective_from": "2026-01-01",
294
+ "effective_to": null
295
+ }
296
+ ]
297
+ },
298
+ {
299
+ "product_id": "international_maxibrief",
300
+ "zone": "zone_1_eu",
301
+ "weight_tier": "W1000",
302
+ "price": [
303
+ {
304
+ "amount": 1900,
305
+ "effective_from": "2026-01-01",
306
+ "effective_to": null
307
+ }
308
+ ]
309
+ },
310
+ {
311
+ "product_id": "international_maxibrief",
312
+ "zone": "world",
313
+ "weight_tier": "W1000",
314
+ "price": [
315
+ {
316
+ "amount": 1900,
317
+ "effective_from": "2026-01-01",
318
+ "effective_to": null
319
+ }
320
+ ]
321
+ },
322
+ {
323
+ "product_id": "international_maxibrief",
324
+ "zone": "zone_1_eu",
325
+ "weight_tier": "W2000",
326
+ "price": [
327
+ {
328
+ "amount": 2600,
329
+ "effective_from": "2026-01-01",
330
+ "effective_to": null
331
+ }
332
+ ]
333
+ },
334
+ {
335
+ "product_id": "international_maxibrief",
336
+ "zone": "world",
337
+ "weight_tier": "W2000",
338
+ "price": [
339
+ {
340
+ "amount": 2600,
341
+ "effective_from": "2026-01-01",
342
+ "effective_to": null
343
+ }
344
+ ]
345
+ }
346
+ ]
347
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "provider": "swisspost",
3
+ "unit": {
4
+ "price": "cents",
5
+ "currency": "CHF"
6
+ },
7
+ "$schema": "https://raw.githubusercontent.com/gruncellka/porto-data/refs/heads/main/porto_data/schemas/service_prices.schema.json",
8
+ "file_type": "service_prices",
9
+ "service_prices": [
10
+ {
11
+ "service_id": "a_mail_plus",
12
+ "price": [
13
+ {
14
+ "amount": 290,
15
+ "effective_from": "2026-01-01",
16
+ "effective_to": null
17
+ }
18
+ ]
19
+ },
20
+ {
21
+ "service_id": "brief_dicke_zuschlag",
22
+ "price": [
23
+ {
24
+ "amount": 200,
25
+ "effective_from": "2026-01-01",
26
+ "effective_to": null
27
+ }
28
+ ]
29
+ }
30
+ ]
31
+ }