@medalsocial/sdk 1.8.0 → 1.10.0
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.
- package/README.md +49 -1
- package/dist/openapi/medal-social.openapi.json +1742 -483
- package/dist/src/index.d.mts +353 -1
- package/dist/src/index.d.ts +353 -1
- package/dist/src/index.js +120 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/index.mjs +120 -0
- package/dist/src/index.mjs.map +1 -1
- package/dist/src/openapi.generated.d.mts +659 -1
- package/dist/src/openapi.generated.d.ts +659 -1
- package/dist/src/openapi.generated.js.map +1 -1
- package/openapi/medal-social.openapi.yaml +806 -4
- package/package.json +1 -1
- package/skills/resources/SKILL.md +7 -0
|
@@ -1229,25 +1229,38 @@
|
|
|
1229
1229
|
}
|
|
1230
1230
|
}
|
|
1231
1231
|
},
|
|
1232
|
-
"/api/v1/bookings/
|
|
1233
|
-
"parameters": [
|
|
1234
|
-
{
|
|
1235
|
-
"$ref": "#/components/parameters/Id"
|
|
1236
|
-
}
|
|
1237
|
-
],
|
|
1232
|
+
"/api/v1/bookings/persons": {
|
|
1238
1233
|
"get": {
|
|
1239
1234
|
"tags": [
|
|
1240
1235
|
"Bookings"
|
|
1241
1236
|
],
|
|
1242
|
-
"operationId": "
|
|
1243
|
-
"summary": "
|
|
1237
|
+
"operationId": "listContactPersons",
|
|
1238
|
+
"summary": "List a contact's persons",
|
|
1239
|
+
"description": "Persons a contact books for — a child, a pet, an employee. No login of their own. Active-only unless `include_inactive` is set.",
|
|
1240
|
+
"parameters": [
|
|
1241
|
+
{
|
|
1242
|
+
"name": "contact_id",
|
|
1243
|
+
"in": "query",
|
|
1244
|
+
"required": true,
|
|
1245
|
+
"schema": {
|
|
1246
|
+
"type": "string"
|
|
1247
|
+
}
|
|
1248
|
+
},
|
|
1249
|
+
{
|
|
1250
|
+
"name": "include_inactive",
|
|
1251
|
+
"in": "query",
|
|
1252
|
+
"schema": {
|
|
1253
|
+
"type": "boolean"
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
],
|
|
1244
1257
|
"responses": {
|
|
1245
1258
|
"200": {
|
|
1246
|
-
"description": "
|
|
1259
|
+
"description": "Contact persons.",
|
|
1247
1260
|
"content": {
|
|
1248
1261
|
"application/json": {
|
|
1249
1262
|
"schema": {
|
|
1250
|
-
"$ref": "#/components/schemas/
|
|
1263
|
+
"$ref": "#/components/schemas/ApiResponse_ContactPersonArray"
|
|
1251
1264
|
}
|
|
1252
1265
|
}
|
|
1253
1266
|
}
|
|
@@ -1257,29 +1270,29 @@
|
|
|
1257
1270
|
}
|
|
1258
1271
|
}
|
|
1259
1272
|
},
|
|
1260
|
-
"
|
|
1273
|
+
"post": {
|
|
1261
1274
|
"tags": [
|
|
1262
1275
|
"Bookings"
|
|
1263
1276
|
],
|
|
1264
|
-
"operationId": "
|
|
1265
|
-
"summary": "
|
|
1277
|
+
"operationId": "createContactPerson",
|
|
1278
|
+
"summary": "Add a person under a contact",
|
|
1266
1279
|
"requestBody": {
|
|
1267
1280
|
"required": true,
|
|
1268
1281
|
"content": {
|
|
1269
1282
|
"application/json": {
|
|
1270
1283
|
"schema": {
|
|
1271
|
-
"$ref": "#/components/schemas/
|
|
1284
|
+
"$ref": "#/components/schemas/CreateContactPersonInput"
|
|
1272
1285
|
}
|
|
1273
1286
|
}
|
|
1274
1287
|
}
|
|
1275
1288
|
},
|
|
1276
1289
|
"responses": {
|
|
1277
|
-
"
|
|
1278
|
-
"description": "
|
|
1290
|
+
"201": {
|
|
1291
|
+
"description": "Created person.",
|
|
1279
1292
|
"content": {
|
|
1280
1293
|
"application/json": {
|
|
1281
1294
|
"schema": {
|
|
1282
|
-
"$ref": "#/components/schemas/
|
|
1295
|
+
"$ref": "#/components/schemas/ApiResponse_ContactPerson"
|
|
1283
1296
|
}
|
|
1284
1297
|
}
|
|
1285
1298
|
}
|
|
@@ -1290,36 +1303,63 @@
|
|
|
1290
1303
|
}
|
|
1291
1304
|
}
|
|
1292
1305
|
},
|
|
1293
|
-
"/api/v1/bookings/
|
|
1294
|
-
"
|
|
1295
|
-
|
|
1296
|
-
"
|
|
1306
|
+
"/api/v1/bookings/relations": {
|
|
1307
|
+
"get": {
|
|
1308
|
+
"tags": [
|
|
1309
|
+
"Bookings"
|
|
1310
|
+
],
|
|
1311
|
+
"operationId": "listContactRelations",
|
|
1312
|
+
"summary": "List a contact's relations",
|
|
1313
|
+
"description": "Directional relations a contact holds, split into outgoing and incoming.",
|
|
1314
|
+
"parameters": [
|
|
1315
|
+
{
|
|
1316
|
+
"name": "contact_id",
|
|
1317
|
+
"in": "query",
|
|
1318
|
+
"required": true,
|
|
1319
|
+
"schema": {
|
|
1320
|
+
"type": "string"
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
],
|
|
1324
|
+
"responses": {
|
|
1325
|
+
"200": {
|
|
1326
|
+
"description": "Outgoing and incoming relations.",
|
|
1327
|
+
"content": {
|
|
1328
|
+
"application/json": {
|
|
1329
|
+
"schema": {
|
|
1330
|
+
"$ref": "#/components/schemas/ApiResponse_ContactRelations"
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
},
|
|
1335
|
+
"default": {
|
|
1336
|
+
"$ref": "#/components/responses/ApiError"
|
|
1337
|
+
}
|
|
1297
1338
|
}
|
|
1298
|
-
|
|
1339
|
+
},
|
|
1299
1340
|
"post": {
|
|
1300
1341
|
"tags": [
|
|
1301
1342
|
"Bookings"
|
|
1302
1343
|
],
|
|
1303
|
-
"operationId": "
|
|
1304
|
-
"summary": "
|
|
1305
|
-
"description": "Staff semantics — the workspace's cancel window is bypassed and the cancellation is attributed to staff.",
|
|
1344
|
+
"operationId": "createContactRelation",
|
|
1345
|
+
"summary": "Create a relation from one contact to another",
|
|
1306
1346
|
"requestBody": {
|
|
1307
1347
|
"required": true,
|
|
1308
1348
|
"content": {
|
|
1309
1349
|
"application/json": {
|
|
1310
1350
|
"schema": {
|
|
1311
|
-
"$ref": "#/components/schemas/
|
|
1351
|
+
"$ref": "#/components/schemas/CreateContactRelationInput"
|
|
1312
1352
|
}
|
|
1313
1353
|
}
|
|
1314
1354
|
}
|
|
1315
1355
|
},
|
|
1316
1356
|
"responses": {
|
|
1317
|
-
"
|
|
1318
|
-
"description": "
|
|
1357
|
+
"201": {
|
|
1358
|
+
"description": "Created relation id.",
|
|
1319
1359
|
"content": {
|
|
1320
1360
|
"application/json": {
|
|
1321
1361
|
"schema": {
|
|
1322
|
-
"$ref": "#/components/schemas/
|
|
1362
|
+
"$ref": "#/components/schemas/ApiResponse_CreateContactRelationResult"
|
|
1323
1363
|
}
|
|
1324
1364
|
}
|
|
1325
1365
|
}
|
|
@@ -1330,36 +1370,81 @@
|
|
|
1330
1370
|
}
|
|
1331
1371
|
}
|
|
1332
1372
|
},
|
|
1333
|
-
"/api/v1/bookings/
|
|
1334
|
-
"
|
|
1335
|
-
|
|
1336
|
-
"
|
|
1373
|
+
"/api/v1/bookings/events": {
|
|
1374
|
+
"get": {
|
|
1375
|
+
"tags": [
|
|
1376
|
+
"Bookings"
|
|
1377
|
+
],
|
|
1378
|
+
"operationId": "listBookingEvents",
|
|
1379
|
+
"summary": "List arrangementer in a date range",
|
|
1380
|
+
"parameters": [
|
|
1381
|
+
{
|
|
1382
|
+
"name": "from",
|
|
1383
|
+
"in": "query",
|
|
1384
|
+
"required": true,
|
|
1385
|
+
"description": "Start of the window, `yyyy-mm-dd`, inclusive.",
|
|
1386
|
+
"schema": {
|
|
1387
|
+
"type": "string",
|
|
1388
|
+
"format": "date"
|
|
1389
|
+
}
|
|
1390
|
+
},
|
|
1391
|
+
{
|
|
1392
|
+
"name": "to",
|
|
1393
|
+
"in": "query",
|
|
1394
|
+
"required": true,
|
|
1395
|
+
"description": "End of the window, `yyyy-mm-dd`, inclusive.",
|
|
1396
|
+
"schema": {
|
|
1397
|
+
"type": "string",
|
|
1398
|
+
"format": "date"
|
|
1399
|
+
}
|
|
1400
|
+
},
|
|
1401
|
+
{
|
|
1402
|
+
"name": "status",
|
|
1403
|
+
"in": "query",
|
|
1404
|
+
"schema": {
|
|
1405
|
+
"$ref": "#/components/schemas/BookingEventStatus"
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
],
|
|
1409
|
+
"responses": {
|
|
1410
|
+
"200": {
|
|
1411
|
+
"description": "Arrangementer in the window.",
|
|
1412
|
+
"content": {
|
|
1413
|
+
"application/json": {
|
|
1414
|
+
"schema": {
|
|
1415
|
+
"$ref": "#/components/schemas/ApiResponse_BookingEventArray"
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
},
|
|
1420
|
+
"default": {
|
|
1421
|
+
"$ref": "#/components/responses/ApiError"
|
|
1422
|
+
}
|
|
1337
1423
|
}
|
|
1338
|
-
|
|
1424
|
+
},
|
|
1339
1425
|
"post": {
|
|
1340
1426
|
"tags": [
|
|
1341
1427
|
"Bookings"
|
|
1342
1428
|
],
|
|
1343
|
-
"operationId": "
|
|
1344
|
-
"summary": "
|
|
1345
|
-
"description": "Staff semantics — the reschedule window is bypassed. The old booking is cancelled and a new one inserted, so the response carries a new booking id and a freshly minted manage token.",
|
|
1429
|
+
"operationId": "createBookingEvent",
|
|
1430
|
+
"summary": "Create an arrangement from a template",
|
|
1346
1431
|
"requestBody": {
|
|
1347
1432
|
"required": true,
|
|
1348
1433
|
"content": {
|
|
1349
1434
|
"application/json": {
|
|
1350
1435
|
"schema": {
|
|
1351
|
-
"$ref": "#/components/schemas/
|
|
1436
|
+
"$ref": "#/components/schemas/CreateBookingEventInput"
|
|
1352
1437
|
}
|
|
1353
1438
|
}
|
|
1354
1439
|
}
|
|
1355
1440
|
},
|
|
1356
1441
|
"responses": {
|
|
1357
|
-
"
|
|
1358
|
-
"description": "
|
|
1442
|
+
"201": {
|
|
1443
|
+
"description": "Created arrangement.",
|
|
1359
1444
|
"content": {
|
|
1360
1445
|
"application/json": {
|
|
1361
1446
|
"schema": {
|
|
1362
|
-
"$ref": "#/components/schemas/
|
|
1447
|
+
"$ref": "#/components/schemas/ApiResponse_BookingEvent"
|
|
1363
1448
|
}
|
|
1364
1449
|
}
|
|
1365
1450
|
}
|
|
@@ -1370,25 +1455,25 @@
|
|
|
1370
1455
|
}
|
|
1371
1456
|
}
|
|
1372
1457
|
},
|
|
1373
|
-
"/api/v1/bookings/{id}
|
|
1458
|
+
"/api/v1/bookings/events/{id}": {
|
|
1374
1459
|
"parameters": [
|
|
1375
1460
|
{
|
|
1376
1461
|
"$ref": "#/components/parameters/Id"
|
|
1377
1462
|
}
|
|
1378
1463
|
],
|
|
1379
|
-
"
|
|
1464
|
+
"get": {
|
|
1380
1465
|
"tags": [
|
|
1381
1466
|
"Bookings"
|
|
1382
1467
|
],
|
|
1383
|
-
"operationId": "
|
|
1384
|
-
"summary": "
|
|
1468
|
+
"operationId": "getBookingEvent",
|
|
1469
|
+
"summary": "Get an arrangement",
|
|
1385
1470
|
"responses": {
|
|
1386
1471
|
"200": {
|
|
1387
|
-
"description": "
|
|
1472
|
+
"description": "Arrangement.",
|
|
1388
1473
|
"content": {
|
|
1389
1474
|
"application/json": {
|
|
1390
1475
|
"schema": {
|
|
1391
|
-
"$ref": "#/components/schemas/
|
|
1476
|
+
"$ref": "#/components/schemas/ApiResponse_BookingEvent"
|
|
1392
1477
|
}
|
|
1393
1478
|
}
|
|
1394
1479
|
}
|
|
@@ -1399,25 +1484,57 @@
|
|
|
1399
1484
|
}
|
|
1400
1485
|
}
|
|
1401
1486
|
},
|
|
1402
|
-
"/api/v1/bookings/
|
|
1487
|
+
"/api/v1/bookings/{id}": {
|
|
1403
1488
|
"parameters": [
|
|
1404
1489
|
{
|
|
1405
|
-
"$ref": "#/components/parameters/
|
|
1490
|
+
"$ref": "#/components/parameters/Id"
|
|
1406
1491
|
}
|
|
1407
1492
|
],
|
|
1408
1493
|
"get": {
|
|
1409
1494
|
"tags": [
|
|
1410
1495
|
"Bookings"
|
|
1411
1496
|
],
|
|
1412
|
-
"operationId": "
|
|
1413
|
-
"summary": "Get
|
|
1497
|
+
"operationId": "getBooking",
|
|
1498
|
+
"summary": "Get a booking",
|
|
1414
1499
|
"responses": {
|
|
1415
1500
|
"200": {
|
|
1416
|
-
"description": "
|
|
1501
|
+
"description": "Booking.",
|
|
1417
1502
|
"content": {
|
|
1418
1503
|
"application/json": {
|
|
1419
1504
|
"schema": {
|
|
1420
|
-
"$ref": "#/components/schemas/
|
|
1505
|
+
"$ref": "#/components/schemas/ApiResponse_Booking"
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
},
|
|
1510
|
+
"default": {
|
|
1511
|
+
"$ref": "#/components/responses/ApiError"
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
},
|
|
1515
|
+
"patch": {
|
|
1516
|
+
"tags": [
|
|
1517
|
+
"Bookings"
|
|
1518
|
+
],
|
|
1519
|
+
"operationId": "updateBooking",
|
|
1520
|
+
"summary": "Annotate a booking",
|
|
1521
|
+
"requestBody": {
|
|
1522
|
+
"required": true,
|
|
1523
|
+
"content": {
|
|
1524
|
+
"application/json": {
|
|
1525
|
+
"schema": {
|
|
1526
|
+
"$ref": "#/components/schemas/UpdateBookingInput"
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
},
|
|
1531
|
+
"responses": {
|
|
1532
|
+
"200": {
|
|
1533
|
+
"description": "The updated booking.",
|
|
1534
|
+
"content": {
|
|
1535
|
+
"application/json": {
|
|
1536
|
+
"schema": {
|
|
1537
|
+
"$ref": "#/components/schemas/ApiResponse_Booking"
|
|
1421
1538
|
}
|
|
1422
1539
|
}
|
|
1423
1540
|
}
|
|
@@ -1428,19 +1545,19 @@
|
|
|
1428
1545
|
}
|
|
1429
1546
|
}
|
|
1430
1547
|
},
|
|
1431
|
-
"/api/v1/bookings/
|
|
1548
|
+
"/api/v1/bookings/{id}/cancel": {
|
|
1432
1549
|
"parameters": [
|
|
1433
1550
|
{
|
|
1434
|
-
"$ref": "#/components/parameters/
|
|
1551
|
+
"$ref": "#/components/parameters/Id"
|
|
1435
1552
|
}
|
|
1436
1553
|
],
|
|
1437
1554
|
"post": {
|
|
1438
1555
|
"tags": [
|
|
1439
1556
|
"Bookings"
|
|
1440
1557
|
],
|
|
1441
|
-
"operationId": "
|
|
1442
|
-
"summary": "Cancel
|
|
1443
|
-
"description": "
|
|
1558
|
+
"operationId": "cancelBooking",
|
|
1559
|
+
"summary": "Cancel a booking as the business",
|
|
1560
|
+
"description": "Staff semantics — the workspace's cancel window is bypassed and the cancellation is attributed to staff.",
|
|
1444
1561
|
"requestBody": {
|
|
1445
1562
|
"required": true,
|
|
1446
1563
|
"content": {
|
|
@@ -1468,19 +1585,19 @@
|
|
|
1468
1585
|
}
|
|
1469
1586
|
}
|
|
1470
1587
|
},
|
|
1471
|
-
"/api/v1/bookings/
|
|
1588
|
+
"/api/v1/bookings/{id}/reschedule": {
|
|
1472
1589
|
"parameters": [
|
|
1473
1590
|
{
|
|
1474
|
-
"$ref": "#/components/parameters/
|
|
1591
|
+
"$ref": "#/components/parameters/Id"
|
|
1475
1592
|
}
|
|
1476
1593
|
],
|
|
1477
1594
|
"post": {
|
|
1478
1595
|
"tags": [
|
|
1479
1596
|
"Bookings"
|
|
1480
1597
|
],
|
|
1481
|
-
"operationId": "
|
|
1482
|
-
"summary": "Reschedule
|
|
1483
|
-
"description": "
|
|
1598
|
+
"operationId": "rescheduleBooking",
|
|
1599
|
+
"summary": "Reschedule a booking as the business",
|
|
1600
|
+
"description": "Staff semantics — the reschedule window is bypassed. The old booking is cancelled and a new one inserted, so the response carries a new booking id and a freshly minted manage token.",
|
|
1484
1601
|
"requestBody": {
|
|
1485
1602
|
"required": true,
|
|
1486
1603
|
"content": {
|
|
@@ -1508,31 +1625,25 @@
|
|
|
1508
1625
|
}
|
|
1509
1626
|
}
|
|
1510
1627
|
},
|
|
1511
|
-
"/api/v1/
|
|
1628
|
+
"/api/v1/bookings/{id}/no-show": {
|
|
1629
|
+
"parameters": [
|
|
1630
|
+
{
|
|
1631
|
+
"$ref": "#/components/parameters/Id"
|
|
1632
|
+
}
|
|
1633
|
+
],
|
|
1512
1634
|
"post": {
|
|
1513
1635
|
"tags": [
|
|
1514
|
-
"
|
|
1636
|
+
"Bookings"
|
|
1515
1637
|
],
|
|
1516
|
-
"operationId": "
|
|
1517
|
-
"summary": "
|
|
1518
|
-
"description": "Always answers 202 `{ status: \"sent\" }`, whether or not the address belongs to a contact — enumeration-safe by design. Rate-limited per address and per caller (`429 RATE_LIMITED`). Not idempotency-keyed. Errors: `400 VALIDATION_ERROR`, `403 FORBIDDEN` (key lacks `write:portal`), `429 RATE_LIMITED`.",
|
|
1519
|
-
"requestBody": {
|
|
1520
|
-
"required": true,
|
|
1521
|
-
"content": {
|
|
1522
|
-
"application/json": {
|
|
1523
|
-
"schema": {
|
|
1524
|
-
"$ref": "#/components/schemas/PortalLoginStartInput"
|
|
1525
|
-
}
|
|
1526
|
-
}
|
|
1527
|
-
}
|
|
1528
|
-
},
|
|
1638
|
+
"operationId": "markBookingNoShow",
|
|
1639
|
+
"summary": "Mark a booking as a no-show",
|
|
1529
1640
|
"responses": {
|
|
1530
|
-
"
|
|
1531
|
-
"description": "
|
|
1641
|
+
"200": {
|
|
1642
|
+
"description": "No-show result.",
|
|
1532
1643
|
"content": {
|
|
1533
1644
|
"application/json": {
|
|
1534
1645
|
"schema": {
|
|
1535
|
-
"$ref": "#/components/schemas/
|
|
1646
|
+
"$ref": "#/components/schemas/ApiResponse_BookingActionResult"
|
|
1536
1647
|
}
|
|
1537
1648
|
}
|
|
1538
1649
|
}
|
|
@@ -1543,31 +1654,36 @@
|
|
|
1543
1654
|
}
|
|
1544
1655
|
}
|
|
1545
1656
|
},
|
|
1546
|
-
"/api/v1/
|
|
1657
|
+
"/api/v1/bookings/{id}/payment": {
|
|
1658
|
+
"parameters": [
|
|
1659
|
+
{
|
|
1660
|
+
"$ref": "#/components/parameters/Id"
|
|
1661
|
+
}
|
|
1662
|
+
],
|
|
1547
1663
|
"post": {
|
|
1548
1664
|
"tags": [
|
|
1549
|
-
"
|
|
1665
|
+
"Bookings"
|
|
1550
1666
|
],
|
|
1551
|
-
"operationId": "
|
|
1552
|
-
"summary": "
|
|
1553
|
-
"description": "
|
|
1667
|
+
"operationId": "startBookingPayment",
|
|
1668
|
+
"summary": "Start a Vipps payment for a booking",
|
|
1669
|
+
"description": "Reserves (or charges) the booking's amount and returns the wallet redirect URL. The customer must have accepted your terms before this call — `terms_accepted` must be literally `true`, and a body omitting it is a 400. One live payment per booking: a second while one is outstanding answers 409, as does a booking that is not payable or a refusal from Vipps. A `return_url` this workspace's own sites do not vouch for answers 422, not 400 — the URL parses, it is just not yours. 403 when the payments switch or the bookings module is off.",
|
|
1554
1670
|
"requestBody": {
|
|
1555
1671
|
"required": true,
|
|
1556
1672
|
"content": {
|
|
1557
1673
|
"application/json": {
|
|
1558
1674
|
"schema": {
|
|
1559
|
-
"$ref": "#/components/schemas/
|
|
1675
|
+
"$ref": "#/components/schemas/StartBookingPaymentInput"
|
|
1560
1676
|
}
|
|
1561
1677
|
}
|
|
1562
1678
|
}
|
|
1563
1679
|
},
|
|
1564
1680
|
"responses": {
|
|
1565
1681
|
"200": {
|
|
1566
|
-
"description": "The
|
|
1682
|
+
"description": "The reference and the SHOW-ONCE redirect URL. The URL is never returned again — the payment behind it expires after ten minutes, so a cached one leads into a payment that no longer exists.",
|
|
1567
1683
|
"content": {
|
|
1568
1684
|
"application/json": {
|
|
1569
1685
|
"schema": {
|
|
1570
|
-
"$ref": "#/components/schemas/
|
|
1686
|
+
"$ref": "#/components/schemas/ApiResponse_BookingPaymentStart"
|
|
1571
1687
|
}
|
|
1572
1688
|
}
|
|
1573
1689
|
}
|
|
@@ -1576,51 +1692,21 @@
|
|
|
1576
1692
|
"$ref": "#/components/responses/ApiError"
|
|
1577
1693
|
}
|
|
1578
1694
|
}
|
|
1579
|
-
}
|
|
1580
|
-
|
|
1581
|
-
"/api/v1/portal/logout": {
|
|
1582
|
-
"parameters": [
|
|
1583
|
-
{
|
|
1584
|
-
"$ref": "#/components/parameters/PortalSession"
|
|
1585
|
-
}
|
|
1586
|
-
],
|
|
1587
|
-
"post": {
|
|
1695
|
+
},
|
|
1696
|
+
"get": {
|
|
1588
1697
|
"tags": [
|
|
1589
|
-
"
|
|
1698
|
+
"Bookings"
|
|
1590
1699
|
],
|
|
1591
|
-
"operationId": "
|
|
1592
|
-
"summary": "
|
|
1593
|
-
"description": "
|
|
1594
|
-
"responses": {
|
|
1595
|
-
"204": {
|
|
1596
|
-
"description": "Session revoked."
|
|
1597
|
-
},
|
|
1598
|
-
"default": {
|
|
1599
|
-
"$ref": "#/components/responses/ApiError"
|
|
1600
|
-
}
|
|
1601
|
-
}
|
|
1602
|
-
}
|
|
1603
|
-
},
|
|
1604
|
-
"/api/v1/portal/me": {
|
|
1605
|
-
"parameters": [
|
|
1606
|
-
{
|
|
1607
|
-
"$ref": "#/components/parameters/PortalSession"
|
|
1608
|
-
}
|
|
1609
|
-
],
|
|
1610
|
-
"get": {
|
|
1611
|
-
"tags": [
|
|
1612
|
-
"Portal"
|
|
1613
|
-
],
|
|
1614
|
-
"operationId": "getPortalProfile",
|
|
1615
|
-
"summary": "The signed-in contact's profile",
|
|
1616
|
-
"description": "Errors: `401 PORTAL_SESSION_REQUIRED`, `401 PORTAL_SESSION_INVALID`, `403 FORBIDDEN` (key lacks `read:portal`), `429 RATE_LIMITED`.",
|
|
1700
|
+
"operationId": "getBookingPayment",
|
|
1701
|
+
"summary": "Read the newest payment attempt on a booking",
|
|
1702
|
+
"description": "Returns the newest attempt only. A booking with no payment yet, an unknown booking id and another workspace's booking all answer 404 alike, so this is not an existence oracle.",
|
|
1617
1703
|
"responses": {
|
|
1618
1704
|
"200": {
|
|
1619
|
-
"description": "
|
|
1705
|
+
"description": "The payment. `redirect_url` is deliberately absent here.",
|
|
1620
1706
|
"content": {
|
|
1621
1707
|
"application/json": {
|
|
1622
1708
|
"schema": {
|
|
1623
|
-
"$ref": "#/components/schemas/
|
|
1709
|
+
"$ref": "#/components/schemas/ApiResponse_BookingPayment"
|
|
1624
1710
|
}
|
|
1625
1711
|
}
|
|
1626
1712
|
}
|
|
@@ -1629,31 +1715,38 @@
|
|
|
1629
1715
|
"$ref": "#/components/responses/ApiError"
|
|
1630
1716
|
}
|
|
1631
1717
|
}
|
|
1632
|
-
}
|
|
1633
|
-
|
|
1718
|
+
}
|
|
1719
|
+
},
|
|
1720
|
+
"/api/v1/bookings/manage/{token}/payment": {
|
|
1721
|
+
"parameters": [
|
|
1722
|
+
{
|
|
1723
|
+
"$ref": "#/components/parameters/ManageToken"
|
|
1724
|
+
}
|
|
1725
|
+
],
|
|
1726
|
+
"post": {
|
|
1634
1727
|
"tags": [
|
|
1635
|
-
"
|
|
1728
|
+
"Bookings"
|
|
1636
1729
|
],
|
|
1637
|
-
"operationId": "
|
|
1638
|
-
"summary": "
|
|
1639
|
-
"description": "
|
|
1730
|
+
"operationId": "startManageBookingPayment",
|
|
1731
|
+
"summary": "Start a payment on the customer's behalf",
|
|
1732
|
+
"description": "The manage-token twin of `startBookingPayment` — same body, same responses; only the credential that authorizes it differs.",
|
|
1640
1733
|
"requestBody": {
|
|
1641
1734
|
"required": true,
|
|
1642
1735
|
"content": {
|
|
1643
1736
|
"application/json": {
|
|
1644
1737
|
"schema": {
|
|
1645
|
-
"$ref": "#/components/schemas/
|
|
1738
|
+
"$ref": "#/components/schemas/StartBookingPaymentInput"
|
|
1646
1739
|
}
|
|
1647
1740
|
}
|
|
1648
1741
|
}
|
|
1649
1742
|
},
|
|
1650
1743
|
"responses": {
|
|
1651
1744
|
"200": {
|
|
1652
|
-
"description": "
|
|
1745
|
+
"description": "The reference and the show-once redirect URL.",
|
|
1653
1746
|
"content": {
|
|
1654
1747
|
"application/json": {
|
|
1655
1748
|
"schema": {
|
|
1656
|
-
"$ref": "#/components/schemas/
|
|
1749
|
+
"$ref": "#/components/schemas/ApiResponse_BookingPaymentStart"
|
|
1657
1750
|
}
|
|
1658
1751
|
}
|
|
1659
1752
|
}
|
|
@@ -1662,28 +1755,21 @@
|
|
|
1662
1755
|
"$ref": "#/components/responses/ApiError"
|
|
1663
1756
|
}
|
|
1664
1757
|
}
|
|
1665
|
-
}
|
|
1666
|
-
},
|
|
1667
|
-
"/api/v1/portal/me/bookings": {
|
|
1668
|
-
"parameters": [
|
|
1669
|
-
{
|
|
1670
|
-
"$ref": "#/components/parameters/PortalSession"
|
|
1671
|
-
}
|
|
1672
|
-
],
|
|
1758
|
+
},
|
|
1673
1759
|
"get": {
|
|
1674
1760
|
"tags": [
|
|
1675
|
-
"
|
|
1761
|
+
"Bookings"
|
|
1676
1762
|
],
|
|
1677
|
-
"operationId": "
|
|
1678
|
-
"summary": "
|
|
1679
|
-
"description": "
|
|
1763
|
+
"operationId": "getManageBookingPayment",
|
|
1764
|
+
"summary": "Read the payment on the customer's own booking",
|
|
1765
|
+
"description": "An unknown token, another workspace's token and a booking with no payment yet all answer 404 alike.",
|
|
1680
1766
|
"responses": {
|
|
1681
1767
|
"200": {
|
|
1682
|
-
"description": "
|
|
1768
|
+
"description": "The payment. `redirect_url` is deliberately absent here.",
|
|
1683
1769
|
"content": {
|
|
1684
1770
|
"application/json": {
|
|
1685
1771
|
"schema": {
|
|
1686
|
-
"$ref": "#/components/schemas/
|
|
1772
|
+
"$ref": "#/components/schemas/ApiResponse_BookingPayment"
|
|
1687
1773
|
}
|
|
1688
1774
|
}
|
|
1689
1775
|
}
|
|
@@ -1694,26 +1780,25 @@
|
|
|
1694
1780
|
}
|
|
1695
1781
|
}
|
|
1696
1782
|
},
|
|
1697
|
-
"/api/v1/
|
|
1783
|
+
"/api/v1/bookings/manage/{token}": {
|
|
1698
1784
|
"parameters": [
|
|
1699
1785
|
{
|
|
1700
|
-
"$ref": "#/components/parameters/
|
|
1786
|
+
"$ref": "#/components/parameters/ManageToken"
|
|
1701
1787
|
}
|
|
1702
1788
|
],
|
|
1703
|
-
"
|
|
1789
|
+
"get": {
|
|
1704
1790
|
"tags": [
|
|
1705
|
-
"
|
|
1791
|
+
"Bookings"
|
|
1706
1792
|
],
|
|
1707
|
-
"operationId": "
|
|
1708
|
-
"summary": "
|
|
1709
|
-
"description": "A synchronous GDPR Art. 15 export of the contact's profile, family, consents and bookings, as one JSON document. Read-only, so not idempotency-keyed. Errors: `401 PORTAL_SESSION_REQUIRED`, `401 PORTAL_SESSION_INVALID`, `403 FORBIDDEN`, `429 RATE_LIMITED`.",
|
|
1793
|
+
"operationId": "getManagedBooking",
|
|
1794
|
+
"summary": "Get the customer manage summary for a token",
|
|
1710
1795
|
"responses": {
|
|
1711
1796
|
"200": {
|
|
1712
|
-
"description": "
|
|
1797
|
+
"description": "Manage summary. An unknown token and a token belonging to another workspace both answer 404, so this is not an existence oracle.",
|
|
1713
1798
|
"content": {
|
|
1714
1799
|
"application/json": {
|
|
1715
1800
|
"schema": {
|
|
1716
|
-
"$ref": "#/components/schemas/
|
|
1801
|
+
"$ref": "#/components/schemas/ApiResponse_ManageSummary"
|
|
1717
1802
|
}
|
|
1718
1803
|
}
|
|
1719
1804
|
}
|
|
@@ -1724,43 +1809,36 @@
|
|
|
1724
1809
|
}
|
|
1725
1810
|
}
|
|
1726
1811
|
},
|
|
1727
|
-
"/api/v1/
|
|
1812
|
+
"/api/v1/bookings/manage/{token}/cancel": {
|
|
1728
1813
|
"parameters": [
|
|
1729
1814
|
{
|
|
1730
|
-
"$ref": "#/components/parameters/
|
|
1815
|
+
"$ref": "#/components/parameters/ManageToken"
|
|
1731
1816
|
}
|
|
1732
1817
|
],
|
|
1733
1818
|
"post": {
|
|
1734
1819
|
"tags": [
|
|
1735
|
-
"
|
|
1820
|
+
"Bookings"
|
|
1736
1821
|
],
|
|
1737
|
-
"operationId": "
|
|
1738
|
-
"summary": "
|
|
1739
|
-
"description": "
|
|
1740
|
-
"
|
|
1741
|
-
"
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1822
|
+
"operationId": "cancelManagedBooking",
|
|
1823
|
+
"summary": "Cancel on the customer's behalf",
|
|
1824
|
+
"description": "Customer semantics — the workspace's cancel window is ENFORCED and the cancellation is attributed to the customer.",
|
|
1825
|
+
"requestBody": {
|
|
1826
|
+
"required": true,
|
|
1827
|
+
"content": {
|
|
1828
|
+
"application/json": {
|
|
1829
|
+
"schema": {
|
|
1830
|
+
"$ref": "#/components/schemas/CancelBookingInput"
|
|
1831
|
+
}
|
|
1832
|
+
}
|
|
1746
1833
|
}
|
|
1747
|
-
}
|
|
1748
|
-
}
|
|
1749
|
-
},
|
|
1750
|
-
"/api/v1/gdpr/export": {
|
|
1751
|
-
"post": {
|
|
1752
|
-
"tags": [
|
|
1753
|
-
"GDPR"
|
|
1754
|
-
],
|
|
1755
|
-
"operationId": "requestGdprExport",
|
|
1756
|
-
"summary": "Request a GDPR export",
|
|
1834
|
+
},
|
|
1757
1835
|
"responses": {
|
|
1758
1836
|
"200": {
|
|
1759
|
-
"description": "
|
|
1837
|
+
"description": "Cancel result.",
|
|
1760
1838
|
"content": {
|
|
1761
1839
|
"application/json": {
|
|
1762
1840
|
"schema": {
|
|
1763
|
-
"$ref": "#/components/schemas/
|
|
1841
|
+
"$ref": "#/components/schemas/ApiResponse_BookingActionResult"
|
|
1764
1842
|
}
|
|
1765
1843
|
}
|
|
1766
1844
|
}
|
|
@@ -1771,20 +1849,36 @@
|
|
|
1771
1849
|
}
|
|
1772
1850
|
}
|
|
1773
1851
|
},
|
|
1774
|
-
"/api/v1/
|
|
1775
|
-
"
|
|
1852
|
+
"/api/v1/bookings/manage/{token}/reschedule": {
|
|
1853
|
+
"parameters": [
|
|
1854
|
+
{
|
|
1855
|
+
"$ref": "#/components/parameters/ManageToken"
|
|
1856
|
+
}
|
|
1857
|
+
],
|
|
1858
|
+
"post": {
|
|
1776
1859
|
"tags": [
|
|
1777
|
-
"
|
|
1860
|
+
"Bookings"
|
|
1778
1861
|
],
|
|
1779
|
-
"operationId": "
|
|
1780
|
-
"summary": "
|
|
1862
|
+
"operationId": "rescheduleManagedBooking",
|
|
1863
|
+
"summary": "Reschedule on the customer's behalf",
|
|
1864
|
+
"description": "Customer semantics — the reschedule window is ENFORCED. The response carries a new booking id and a new manage token; the old token stops working.",
|
|
1865
|
+
"requestBody": {
|
|
1866
|
+
"required": true,
|
|
1867
|
+
"content": {
|
|
1868
|
+
"application/json": {
|
|
1869
|
+
"schema": {
|
|
1870
|
+
"$ref": "#/components/schemas/RescheduleBookingInput"
|
|
1871
|
+
}
|
|
1872
|
+
}
|
|
1873
|
+
}
|
|
1874
|
+
},
|
|
1781
1875
|
"responses": {
|
|
1782
1876
|
"200": {
|
|
1783
|
-
"description": "
|
|
1877
|
+
"description": "Reschedule result.",
|
|
1784
1878
|
"content": {
|
|
1785
1879
|
"application/json": {
|
|
1786
1880
|
"schema": {
|
|
1787
|
-
"$ref": "#/components/schemas/
|
|
1881
|
+
"$ref": "#/components/schemas/ApiResponse_BookingRescheduleResult"
|
|
1788
1882
|
}
|
|
1789
1883
|
}
|
|
1790
1884
|
}
|
|
@@ -1795,25 +1889,31 @@
|
|
|
1795
1889
|
}
|
|
1796
1890
|
}
|
|
1797
1891
|
},
|
|
1798
|
-
"/api/v1/
|
|
1799
|
-
"
|
|
1800
|
-
{
|
|
1801
|
-
"$ref": "#/components/parameters/Id"
|
|
1802
|
-
}
|
|
1803
|
-
],
|
|
1804
|
-
"get": {
|
|
1892
|
+
"/api/v1/portal/login/start": {
|
|
1893
|
+
"post": {
|
|
1805
1894
|
"tags": [
|
|
1806
|
-
"
|
|
1895
|
+
"Portal"
|
|
1807
1896
|
],
|
|
1808
|
-
"operationId": "
|
|
1809
|
-
"summary": "
|
|
1897
|
+
"operationId": "startPortalLogin",
|
|
1898
|
+
"summary": "E-mail a one-time login code",
|
|
1899
|
+
"description": "Always answers 202 `{ status: \"sent\" }`, whether or not the address belongs to a contact — enumeration-safe by design. Rate-limited per address and per caller (`429 RATE_LIMITED`). Not idempotency-keyed. Errors: `400 VALIDATION_ERROR`, `403 FORBIDDEN` (key lacks `write:portal`), `429 RATE_LIMITED`.",
|
|
1900
|
+
"requestBody": {
|
|
1901
|
+
"required": true,
|
|
1902
|
+
"content": {
|
|
1903
|
+
"application/json": {
|
|
1904
|
+
"schema": {
|
|
1905
|
+
"$ref": "#/components/schemas/PortalLoginStartInput"
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
},
|
|
1810
1910
|
"responses": {
|
|
1811
|
-
"
|
|
1812
|
-
"description": "
|
|
1911
|
+
"202": {
|
|
1912
|
+
"description": "Code queued (or silently not, for an unknown address).",
|
|
1813
1913
|
"content": {
|
|
1814
1914
|
"application/json": {
|
|
1815
1915
|
"schema": {
|
|
1816
|
-
"$ref": "#/components/schemas/
|
|
1916
|
+
"$ref": "#/components/schemas/ApiResponse_PortalLoginStartResult"
|
|
1817
1917
|
}
|
|
1818
1918
|
}
|
|
1819
1919
|
}
|
|
@@ -1824,30 +1924,31 @@
|
|
|
1824
1924
|
}
|
|
1825
1925
|
}
|
|
1826
1926
|
},
|
|
1827
|
-
"/api/v1/
|
|
1927
|
+
"/api/v1/portal/login/verify": {
|
|
1828
1928
|
"post": {
|
|
1829
1929
|
"tags": [
|
|
1830
|
-
"
|
|
1930
|
+
"Portal"
|
|
1831
1931
|
],
|
|
1832
|
-
"operationId": "
|
|
1833
|
-
"summary": "
|
|
1932
|
+
"operationId": "verifyPortalLogin",
|
|
1933
|
+
"summary": "Exchange the e-mailed code for a session",
|
|
1934
|
+
"description": "A wrong, burned or expired code all answer `401 PORTAL_CODE_INVALID` — the three are not distinguished, so the response is not an oracle for which codes exist. The returned `session_token` is a bearer credential for ONE contact: keep it in an HttpOnly cookie on the site's server and never hand it to the browser. Not idempotency-keyed. Errors: `400 VALIDATION_ERROR`, `401 PORTAL_CODE_INVALID`, `403 FORBIDDEN`, `429 RATE_LIMITED`.",
|
|
1834
1935
|
"requestBody": {
|
|
1835
1936
|
"required": true,
|
|
1836
1937
|
"content": {
|
|
1837
1938
|
"application/json": {
|
|
1838
1939
|
"schema": {
|
|
1839
|
-
"$ref": "#/components/schemas/
|
|
1940
|
+
"$ref": "#/components/schemas/PortalVerifyInput"
|
|
1840
1941
|
}
|
|
1841
1942
|
}
|
|
1842
1943
|
}
|
|
1843
1944
|
},
|
|
1844
1945
|
"responses": {
|
|
1845
1946
|
"200": {
|
|
1846
|
-
"description": "
|
|
1947
|
+
"description": "The new session.",
|
|
1847
1948
|
"content": {
|
|
1848
1949
|
"application/json": {
|
|
1849
1950
|
"schema": {
|
|
1850
|
-
"$ref": "#/components/schemas/
|
|
1951
|
+
"$ref": "#/components/schemas/ApiResponse_PortalSession"
|
|
1851
1952
|
}
|
|
1852
1953
|
}
|
|
1853
1954
|
}
|
|
@@ -1858,31 +1959,49 @@
|
|
|
1858
1959
|
}
|
|
1859
1960
|
}
|
|
1860
1961
|
},
|
|
1861
|
-
"/api/v1/
|
|
1962
|
+
"/api/v1/portal/logout": {
|
|
1862
1963
|
"parameters": [
|
|
1863
1964
|
{
|
|
1864
|
-
"
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1965
|
+
"$ref": "#/components/parameters/PortalSession"
|
|
1966
|
+
}
|
|
1967
|
+
],
|
|
1968
|
+
"post": {
|
|
1969
|
+
"tags": [
|
|
1970
|
+
"Portal"
|
|
1971
|
+
],
|
|
1972
|
+
"operationId": "logoutPortal",
|
|
1973
|
+
"summary": "Revoke the session",
|
|
1974
|
+
"description": "Revoking twice reaches the same state — the second call answers `401 PORTAL_SESSION_INVALID`. Not idempotency-keyed. Errors: `401 PORTAL_SESSION_REQUIRED` (header missing), `401 PORTAL_SESSION_INVALID` (unknown, expired or revoked), `403 FORBIDDEN`, `429 RATE_LIMITED`.",
|
|
1975
|
+
"responses": {
|
|
1976
|
+
"204": {
|
|
1977
|
+
"description": "Session revoked."
|
|
1978
|
+
},
|
|
1979
|
+
"default": {
|
|
1980
|
+
"$ref": "#/components/responses/ApiError"
|
|
1870
1981
|
}
|
|
1871
1982
|
}
|
|
1983
|
+
}
|
|
1984
|
+
},
|
|
1985
|
+
"/api/v1/portal/me": {
|
|
1986
|
+
"parameters": [
|
|
1987
|
+
{
|
|
1988
|
+
"$ref": "#/components/parameters/PortalSession"
|
|
1989
|
+
}
|
|
1872
1990
|
],
|
|
1873
1991
|
"get": {
|
|
1874
1992
|
"tags": [
|
|
1875
|
-
"
|
|
1993
|
+
"Portal"
|
|
1876
1994
|
],
|
|
1877
|
-
"operationId": "
|
|
1878
|
-
"summary": "
|
|
1995
|
+
"operationId": "getPortalProfile",
|
|
1996
|
+
"summary": "The signed-in contact's profile",
|
|
1997
|
+
"description": "Errors: `401 PORTAL_SESSION_REQUIRED`, `401 PORTAL_SESSION_INVALID`, `403 FORBIDDEN` (key lacks `read:portal`), `429 RATE_LIMITED`.",
|
|
1879
1998
|
"responses": {
|
|
1880
1999
|
"200": {
|
|
1881
|
-
"description": "
|
|
2000
|
+
"description": "Profile.",
|
|
1882
2001
|
"content": {
|
|
1883
2002
|
"application/json": {
|
|
1884
2003
|
"schema": {
|
|
1885
|
-
"$ref": "#/components/schemas/
|
|
2004
|
+
"$ref": "#/components/schemas/ApiResponse_PortalProfile"
|
|
1886
2005
|
}
|
|
1887
2006
|
}
|
|
1888
2007
|
}
|
|
@@ -1891,32 +2010,31 @@
|
|
|
1891
2010
|
"$ref": "#/components/responses/ApiError"
|
|
1892
2011
|
}
|
|
1893
2012
|
}
|
|
1894
|
-
}
|
|
1895
|
-
|
|
1896
|
-
"/api/cookie-consent": {
|
|
1897
|
-
"post": {
|
|
2013
|
+
},
|
|
2014
|
+
"patch": {
|
|
1898
2015
|
"tags": [
|
|
1899
|
-
"
|
|
2016
|
+
"Portal"
|
|
1900
2017
|
],
|
|
1901
|
-
"operationId": "
|
|
1902
|
-
"summary": "
|
|
2018
|
+
"operationId": "updatePortalProfile",
|
|
2019
|
+
"summary": "Update the signed-in contact's profile",
|
|
2020
|
+
"description": "Only the supplied fields change. `phone: null` clears the number, `family` replaces the whole list, and `marketing_consent` records a `marketing_email` consent decision with source `portal`. Answers the profile as it is after the change. Errors: `400 VALIDATION_ERROR`, `401 PORTAL_SESSION_REQUIRED`, `401 PORTAL_SESSION_INVALID`, `403 FORBIDDEN` (key lacks `write:portal`), `429 RATE_LIMITED`.",
|
|
1903
2021
|
"requestBody": {
|
|
1904
2022
|
"required": true,
|
|
1905
2023
|
"content": {
|
|
1906
2024
|
"application/json": {
|
|
1907
2025
|
"schema": {
|
|
1908
|
-
"$ref": "#/components/schemas/
|
|
2026
|
+
"$ref": "#/components/schemas/PortalProfilePatch"
|
|
1909
2027
|
}
|
|
1910
2028
|
}
|
|
1911
2029
|
}
|
|
1912
2030
|
},
|
|
1913
2031
|
"responses": {
|
|
1914
2032
|
"200": {
|
|
1915
|
-
"description": "
|
|
2033
|
+
"description": "Updated profile.",
|
|
1916
2034
|
"content": {
|
|
1917
2035
|
"application/json": {
|
|
1918
2036
|
"schema": {
|
|
1919
|
-
"$ref": "#/components/schemas/
|
|
2037
|
+
"$ref": "#/components/schemas/ApiResponse_PortalProfile"
|
|
1920
2038
|
}
|
|
1921
2039
|
}
|
|
1922
2040
|
}
|
|
@@ -1927,20 +2045,26 @@
|
|
|
1927
2045
|
}
|
|
1928
2046
|
}
|
|
1929
2047
|
},
|
|
1930
|
-
"/api/v1/me/
|
|
2048
|
+
"/api/v1/portal/me/bookings": {
|
|
2049
|
+
"parameters": [
|
|
2050
|
+
{
|
|
2051
|
+
"$ref": "#/components/parameters/PortalSession"
|
|
2052
|
+
}
|
|
2053
|
+
],
|
|
1931
2054
|
"get": {
|
|
1932
2055
|
"tags": [
|
|
1933
|
-
"
|
|
2056
|
+
"Portal"
|
|
1934
2057
|
],
|
|
1935
|
-
"operationId": "
|
|
1936
|
-
"summary": "
|
|
2058
|
+
"operationId": "listPortalBookings",
|
|
2059
|
+
"summary": "The signed-in contact's bookings",
|
|
2060
|
+
"description": "Split into `upcoming` and `past`. An upcoming booking still inside the workspace's policy windows carries `manage_token` and `can_manage: true`; the token opens the site's manage page. Errors: `401 PORTAL_SESSION_REQUIRED`, `401 PORTAL_SESSION_INVALID`, `403 FORBIDDEN`, `429 RATE_LIMITED`.",
|
|
1937
2061
|
"responses": {
|
|
1938
2062
|
"200": {
|
|
1939
|
-
"description": "
|
|
2063
|
+
"description": "Bookings.",
|
|
1940
2064
|
"content": {
|
|
1941
2065
|
"application/json": {
|
|
1942
2066
|
"schema": {
|
|
1943
|
-
"$ref": "#/components/schemas/
|
|
2067
|
+
"$ref": "#/components/schemas/ApiResponse_PortalBookings"
|
|
1944
2068
|
}
|
|
1945
2069
|
}
|
|
1946
2070
|
}
|
|
@@ -1951,73 +2075,26 @@
|
|
|
1951
2075
|
}
|
|
1952
2076
|
}
|
|
1953
2077
|
},
|
|
1954
|
-
"/api/v1/
|
|
1955
|
-
"
|
|
2078
|
+
"/api/v1/portal/me/export": {
|
|
2079
|
+
"parameters": [
|
|
2080
|
+
{
|
|
2081
|
+
"$ref": "#/components/parameters/PortalSession"
|
|
2082
|
+
}
|
|
2083
|
+
],
|
|
2084
|
+
"post": {
|
|
1956
2085
|
"tags": [
|
|
1957
|
-
"
|
|
1958
|
-
],
|
|
1959
|
-
"operationId": "listHelpdeskConversations",
|
|
1960
|
-
"summary": "List helpdesk conversations",
|
|
1961
|
-
"parameters": [
|
|
1962
|
-
{
|
|
1963
|
-
"name": "limit",
|
|
1964
|
-
"in": "query",
|
|
1965
|
-
"schema": {
|
|
1966
|
-
"type": "integer",
|
|
1967
|
-
"minimum": 1,
|
|
1968
|
-
"maximum": 100
|
|
1969
|
-
}
|
|
1970
|
-
},
|
|
1971
|
-
{
|
|
1972
|
-
"$ref": "#/components/parameters/Cursor"
|
|
1973
|
-
},
|
|
1974
|
-
{
|
|
1975
|
-
"name": "status",
|
|
1976
|
-
"in": "query",
|
|
1977
|
-
"schema": {
|
|
1978
|
-
"$ref": "#/components/schemas/HelpdeskConversationStatus"
|
|
1979
|
-
}
|
|
1980
|
-
},
|
|
1981
|
-
{
|
|
1982
|
-
"name": "assignee_user_id",
|
|
1983
|
-
"in": "query",
|
|
1984
|
-
"schema": {
|
|
1985
|
-
"type": "string"
|
|
1986
|
-
},
|
|
1987
|
-
"description": "Only conversations assigned to this user."
|
|
1988
|
-
},
|
|
1989
|
-
{
|
|
1990
|
-
"name": "requester",
|
|
1991
|
-
"in": "query",
|
|
1992
|
-
"schema": {
|
|
1993
|
-
"type": "string"
|
|
1994
|
-
},
|
|
1995
|
-
"description": "Match against visitor name/email."
|
|
1996
|
-
},
|
|
1997
|
-
{
|
|
1998
|
-
"name": "query",
|
|
1999
|
-
"in": "query",
|
|
2000
|
-
"schema": {
|
|
2001
|
-
"type": "string"
|
|
2002
|
-
},
|
|
2003
|
-
"description": "Free-text search query."
|
|
2004
|
-
},
|
|
2005
|
-
{
|
|
2006
|
-
"name": "channels",
|
|
2007
|
-
"in": "query",
|
|
2008
|
-
"schema": {
|
|
2009
|
-
"type": "string"
|
|
2010
|
-
},
|
|
2011
|
-
"description": "Comma-separated channel types (e.g. `widget,whatsapp`)."
|
|
2012
|
-
}
|
|
2086
|
+
"Portal"
|
|
2013
2087
|
],
|
|
2088
|
+
"operationId": "exportPortalData",
|
|
2089
|
+
"summary": "Export everything held about the signed-in contact",
|
|
2090
|
+
"description": "A synchronous GDPR Art. 15 export of the contact's profile, family, consents and bookings, as one JSON document. Unlike `GET /api/v1/portal/me`, `contact.persons` here includes inactive persons so the export is a complete dump. `relations` lists every relation the contact is a party to, exposing only the counterpart's display name. Read-only, so not idempotency-keyed. Errors: `401 PORTAL_SESSION_REQUIRED`, `401 PORTAL_SESSION_INVALID`, `403 FORBIDDEN`, `429 RATE_LIMITED`.",
|
|
2014
2091
|
"responses": {
|
|
2015
2092
|
"200": {
|
|
2016
|
-
"description": "
|
|
2093
|
+
"description": "The export.",
|
|
2017
2094
|
"content": {
|
|
2018
2095
|
"application/json": {
|
|
2019
2096
|
"schema": {
|
|
2020
|
-
"$ref": "#/components/schemas/
|
|
2097
|
+
"$ref": "#/components/schemas/ApiResponse_PortalExport"
|
|
2021
2098
|
}
|
|
2022
2099
|
}
|
|
2023
2100
|
}
|
|
@@ -2028,25 +2105,43 @@
|
|
|
2028
2105
|
}
|
|
2029
2106
|
}
|
|
2030
2107
|
},
|
|
2031
|
-
"/api/v1/
|
|
2108
|
+
"/api/v1/portal/me/delete": {
|
|
2032
2109
|
"parameters": [
|
|
2033
2110
|
{
|
|
2034
|
-
"$ref": "#/components/parameters/
|
|
2111
|
+
"$ref": "#/components/parameters/PortalSession"
|
|
2035
2112
|
}
|
|
2036
2113
|
],
|
|
2037
|
-
"
|
|
2114
|
+
"post": {
|
|
2038
2115
|
"tags": [
|
|
2039
|
-
"
|
|
2116
|
+
"Portal"
|
|
2040
2117
|
],
|
|
2041
|
-
"operationId": "
|
|
2042
|
-
"summary": "
|
|
2118
|
+
"operationId": "deletePortalAccount",
|
|
2119
|
+
"summary": "Erase the signed-in contact",
|
|
2120
|
+
"description": "GDPR Art. 17 erasure. The session is revoked as part of the deletion, so a retry answers `401 PORTAL_SESSION_INVALID` rather than deleting anything else. Not idempotency-keyed. Errors: `401 PORTAL_SESSION_REQUIRED`, `401 PORTAL_SESSION_INVALID`, `403 FORBIDDEN` (key lacks `write:portal`), `429 RATE_LIMITED`.",
|
|
2121
|
+
"responses": {
|
|
2122
|
+
"204": {
|
|
2123
|
+
"description": "Contact erased and session revoked."
|
|
2124
|
+
},
|
|
2125
|
+
"default": {
|
|
2126
|
+
"$ref": "#/components/responses/ApiError"
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2129
|
+
}
|
|
2130
|
+
},
|
|
2131
|
+
"/api/v1/gdpr/export": {
|
|
2132
|
+
"post": {
|
|
2133
|
+
"tags": [
|
|
2134
|
+
"GDPR"
|
|
2135
|
+
],
|
|
2136
|
+
"operationId": "requestGdprExport",
|
|
2137
|
+
"summary": "Request a GDPR export",
|
|
2043
2138
|
"responses": {
|
|
2044
2139
|
"200": {
|
|
2045
|
-
"description": "
|
|
2140
|
+
"description": "Export request reference.",
|
|
2046
2141
|
"content": {
|
|
2047
2142
|
"application/json": {
|
|
2048
2143
|
"schema": {
|
|
2049
|
-
"$ref": "#/components/schemas/
|
|
2144
|
+
"$ref": "#/components/schemas/ApiResponse_GdprExportRequest"
|
|
2050
2145
|
}
|
|
2051
2146
|
}
|
|
2052
2147
|
}
|
|
@@ -2055,31 +2150,22 @@
|
|
|
2055
2150
|
"$ref": "#/components/responses/ApiError"
|
|
2056
2151
|
}
|
|
2057
2152
|
}
|
|
2058
|
-
}
|
|
2059
|
-
|
|
2153
|
+
}
|
|
2154
|
+
},
|
|
2155
|
+
"/api/v1/gdpr/exports": {
|
|
2156
|
+
"get": {
|
|
2060
2157
|
"tags": [
|
|
2061
|
-
"
|
|
2158
|
+
"GDPR"
|
|
2062
2159
|
],
|
|
2063
|
-
"operationId": "
|
|
2064
|
-
"summary": "
|
|
2065
|
-
"description": "Set `status` and/or `assignee_user_id` (`null` unassigns). At least one field is required. Capability-scoped tokens must send `Idempotency-Key` and `X-Capability-Confirmation` headers on this route; API keys with legacy scopes may omit them.",
|
|
2066
|
-
"requestBody": {
|
|
2067
|
-
"required": true,
|
|
2068
|
-
"content": {
|
|
2069
|
-
"application/json": {
|
|
2070
|
-
"schema": {
|
|
2071
|
-
"$ref": "#/components/schemas/UpdateHelpdeskConversationInput"
|
|
2072
|
-
}
|
|
2073
|
-
}
|
|
2074
|
-
}
|
|
2075
|
-
},
|
|
2160
|
+
"operationId": "listGdprExports",
|
|
2161
|
+
"summary": "List GDPR exports",
|
|
2076
2162
|
"responses": {
|
|
2077
2163
|
"200": {
|
|
2078
|
-
"description": "
|
|
2164
|
+
"description": "Export requests.",
|
|
2079
2165
|
"content": {
|
|
2080
2166
|
"application/json": {
|
|
2081
2167
|
"schema": {
|
|
2082
|
-
"$ref": "#/components/schemas/
|
|
2168
|
+
"$ref": "#/components/schemas/ApiResponse_GdprExportArray"
|
|
2083
2169
|
}
|
|
2084
2170
|
}
|
|
2085
2171
|
}
|
|
@@ -2090,7 +2176,7 @@
|
|
|
2090
2176
|
}
|
|
2091
2177
|
}
|
|
2092
2178
|
},
|
|
2093
|
-
"/api/v1/
|
|
2179
|
+
"/api/v1/gdpr/exports/{id}": {
|
|
2094
2180
|
"parameters": [
|
|
2095
2181
|
{
|
|
2096
2182
|
"$ref": "#/components/parameters/Id"
|
|
@@ -2098,41 +2184,17 @@
|
|
|
2098
2184
|
],
|
|
2099
2185
|
"get": {
|
|
2100
2186
|
"tags": [
|
|
2101
|
-
"
|
|
2102
|
-
],
|
|
2103
|
-
"operationId": "listHelpdeskConversationMessages",
|
|
2104
|
-
"summary": "List conversation messages",
|
|
2105
|
-
"parameters": [
|
|
2106
|
-
{
|
|
2107
|
-
"name": "limit",
|
|
2108
|
-
"in": "query",
|
|
2109
|
-
"schema": {
|
|
2110
|
-
"type": "integer",
|
|
2111
|
-
"minimum": 1,
|
|
2112
|
-
"maximum": 50
|
|
2113
|
-
}
|
|
2114
|
-
},
|
|
2115
|
-
{
|
|
2116
|
-
"$ref": "#/components/parameters/Cursor"
|
|
2117
|
-
}
|
|
2187
|
+
"GDPR"
|
|
2118
2188
|
],
|
|
2189
|
+
"operationId": "getGdprExport",
|
|
2190
|
+
"summary": "Get a GDPR export",
|
|
2119
2191
|
"responses": {
|
|
2120
2192
|
"200": {
|
|
2121
|
-
"description": "
|
|
2122
|
-
"content": {
|
|
2123
|
-
"application/json": {
|
|
2124
|
-
"schema": {
|
|
2125
|
-
"$ref": "#/components/schemas/PaginatedResponse_HelpdeskMessage"
|
|
2126
|
-
}
|
|
2127
|
-
}
|
|
2128
|
-
}
|
|
2129
|
-
},
|
|
2130
|
-
"404": {
|
|
2131
|
-
"description": "Conversation not found.",
|
|
2193
|
+
"description": "Export request.",
|
|
2132
2194
|
"content": {
|
|
2133
2195
|
"application/json": {
|
|
2134
2196
|
"schema": {
|
|
2135
|
-
"$ref": "#/components/schemas/
|
|
2197
|
+
"$ref": "#/components/schemas/ApiResponse_GdprExport"
|
|
2136
2198
|
}
|
|
2137
2199
|
}
|
|
2138
2200
|
}
|
|
@@ -2143,31 +2205,30 @@
|
|
|
2143
2205
|
}
|
|
2144
2206
|
}
|
|
2145
2207
|
},
|
|
2146
|
-
"/api/v1/
|
|
2208
|
+
"/api/v1/gdpr/consent": {
|
|
2147
2209
|
"post": {
|
|
2148
2210
|
"tags": [
|
|
2149
|
-
"
|
|
2211
|
+
"GDPR"
|
|
2150
2212
|
],
|
|
2151
|
-
"operationId": "
|
|
2152
|
-
"summary": "
|
|
2153
|
-
"description": "Send an `Idempotency-Key` header so retried requests do not create duplicate messages — it is required for capability-scoped tokens (together with `X-Capability-Confirmation`).",
|
|
2213
|
+
"operationId": "recordGdprConsent",
|
|
2214
|
+
"summary": "Record GDPR consent",
|
|
2154
2215
|
"requestBody": {
|
|
2155
2216
|
"required": true,
|
|
2156
2217
|
"content": {
|
|
2157
2218
|
"application/json": {
|
|
2158
2219
|
"schema": {
|
|
2159
|
-
"$ref": "#/components/schemas/
|
|
2220
|
+
"$ref": "#/components/schemas/RecordConsentInput"
|
|
2160
2221
|
}
|
|
2161
2222
|
}
|
|
2162
2223
|
}
|
|
2163
2224
|
},
|
|
2164
2225
|
"responses": {
|
|
2165
|
-
"
|
|
2166
|
-
"description": "
|
|
2226
|
+
"200": {
|
|
2227
|
+
"description": "Consent reference.",
|
|
2167
2228
|
"content": {
|
|
2168
2229
|
"application/json": {
|
|
2169
2230
|
"schema": {
|
|
2170
|
-
"$ref": "#/components/schemas/
|
|
2231
|
+
"$ref": "#/components/schemas/ApiResponse_ConsentResult"
|
|
2171
2232
|
}
|
|
2172
2233
|
}
|
|
2173
2234
|
}
|
|
@@ -2178,20 +2239,31 @@
|
|
|
2178
2239
|
}
|
|
2179
2240
|
}
|
|
2180
2241
|
},
|
|
2181
|
-
"/api/v1/
|
|
2242
|
+
"/api/v1/gdpr/consent/{email}": {
|
|
2243
|
+
"parameters": [
|
|
2244
|
+
{
|
|
2245
|
+
"name": "email",
|
|
2246
|
+
"in": "path",
|
|
2247
|
+
"required": true,
|
|
2248
|
+
"schema": {
|
|
2249
|
+
"type": "string",
|
|
2250
|
+
"format": "email"
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
],
|
|
2182
2254
|
"get": {
|
|
2183
2255
|
"tags": [
|
|
2184
|
-
"
|
|
2256
|
+
"GDPR"
|
|
2185
2257
|
],
|
|
2186
|
-
"operationId": "
|
|
2187
|
-
"summary": "
|
|
2258
|
+
"operationId": "getGdprConsent",
|
|
2259
|
+
"summary": "Get GDPR consent records",
|
|
2188
2260
|
"responses": {
|
|
2189
2261
|
"200": {
|
|
2190
|
-
"description": "
|
|
2262
|
+
"description": "Consent records.",
|
|
2191
2263
|
"content": {
|
|
2192
2264
|
"application/json": {
|
|
2193
2265
|
"schema": {
|
|
2194
|
-
"$ref": "#/components/schemas/
|
|
2266
|
+
"$ref": "#/components/schemas/ApiResponse_ConsentRecordArray"
|
|
2195
2267
|
}
|
|
2196
2268
|
}
|
|
2197
2269
|
}
|
|
@@ -2200,31 +2272,32 @@
|
|
|
2200
2272
|
"$ref": "#/components/responses/ApiError"
|
|
2201
2273
|
}
|
|
2202
2274
|
}
|
|
2203
|
-
}
|
|
2275
|
+
}
|
|
2276
|
+
},
|
|
2277
|
+
"/api/cookie-consent": {
|
|
2204
2278
|
"post": {
|
|
2205
2279
|
"tags": [
|
|
2206
|
-
"
|
|
2280
|
+
"GDPR"
|
|
2207
2281
|
],
|
|
2208
|
-
"operationId": "
|
|
2209
|
-
"summary": "
|
|
2210
|
-
"description": "The response's `data.secret` contains the signing secret EXACTLY ONCE — it can never be retrieved again, so store it securely immediately. An idempotent replay (same `Idempotency-Key`) returns the existing endpoint WITHOUT `secret`. Deliveries are HTTP POSTs signed with `X-Medal-Signature: sha256=<base64(HMAC-SHA256(\"{timestamp}.{rawBody}\", secret))>` plus `X-Medal-Timestamp`, `X-Medal-Event`, and `X-Medal-Delivery-Id` / `Idempotency-Key` headers.",
|
|
2282
|
+
"operationId": "recordCookieConsent",
|
|
2283
|
+
"summary": "Record cookie consent",
|
|
2211
2284
|
"requestBody": {
|
|
2212
2285
|
"required": true,
|
|
2213
2286
|
"content": {
|
|
2214
2287
|
"application/json": {
|
|
2215
2288
|
"schema": {
|
|
2216
|
-
"$ref": "#/components/schemas/
|
|
2289
|
+
"$ref": "#/components/schemas/CookieConsentInput"
|
|
2217
2290
|
}
|
|
2218
2291
|
}
|
|
2219
2292
|
}
|
|
2220
2293
|
},
|
|
2221
2294
|
"responses": {
|
|
2222
|
-
"
|
|
2223
|
-
"description": "
|
|
2295
|
+
"200": {
|
|
2296
|
+
"description": "Cookie consent result.",
|
|
2224
2297
|
"content": {
|
|
2225
2298
|
"application/json": {
|
|
2226
2299
|
"schema": {
|
|
2227
|
-
"$ref": "#/components/schemas/
|
|
2300
|
+
"$ref": "#/components/schemas/CookieConsentResult"
|
|
2228
2301
|
}
|
|
2229
2302
|
}
|
|
2230
2303
|
}
|
|
@@ -2235,25 +2308,20 @@
|
|
|
2235
2308
|
}
|
|
2236
2309
|
}
|
|
2237
2310
|
},
|
|
2238
|
-
"/api/v1/
|
|
2239
|
-
"parameters": [
|
|
2240
|
-
{
|
|
2241
|
-
"$ref": "#/components/parameters/Id"
|
|
2242
|
-
}
|
|
2243
|
-
],
|
|
2311
|
+
"/api/v1/me/workspaces": {
|
|
2244
2312
|
"get": {
|
|
2245
2313
|
"tags": [
|
|
2246
|
-
"
|
|
2314
|
+
"Workspaces"
|
|
2247
2315
|
],
|
|
2248
|
-
"operationId": "
|
|
2249
|
-
"summary": "
|
|
2316
|
+
"operationId": "listWorkspaces",
|
|
2317
|
+
"summary": "List accessible workspaces",
|
|
2250
2318
|
"responses": {
|
|
2251
2319
|
"200": {
|
|
2252
|
-
"description": "
|
|
2320
|
+
"description": "Workspaces.",
|
|
2253
2321
|
"content": {
|
|
2254
2322
|
"application/json": {
|
|
2255
2323
|
"schema": {
|
|
2256
|
-
"$ref": "#/components/schemas/
|
|
2324
|
+
"$ref": "#/components/schemas/ApiResponse_WorkspaceArray"
|
|
2257
2325
|
}
|
|
2258
2326
|
}
|
|
2259
2327
|
}
|
|
@@ -2262,31 +2330,104 @@
|
|
|
2262
2330
|
"$ref": "#/components/responses/ApiError"
|
|
2263
2331
|
}
|
|
2264
2332
|
}
|
|
2265
|
-
}
|
|
2266
|
-
|
|
2333
|
+
}
|
|
2334
|
+
},
|
|
2335
|
+
"/api/v1/helpdesk/conversations": {
|
|
2336
|
+
"get": {
|
|
2267
2337
|
"tags": [
|
|
2268
|
-
"
|
|
2338
|
+
"Helpdesk"
|
|
2269
2339
|
],
|
|
2270
|
-
"operationId": "
|
|
2271
|
-
"summary": "
|
|
2272
|
-
"
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
"
|
|
2277
|
-
"
|
|
2278
|
-
|
|
2340
|
+
"operationId": "listHelpdeskConversations",
|
|
2341
|
+
"summary": "List helpdesk conversations",
|
|
2342
|
+
"parameters": [
|
|
2343
|
+
{
|
|
2344
|
+
"name": "limit",
|
|
2345
|
+
"in": "query",
|
|
2346
|
+
"schema": {
|
|
2347
|
+
"type": "integer",
|
|
2348
|
+
"minimum": 1,
|
|
2349
|
+
"maximum": 100
|
|
2350
|
+
}
|
|
2351
|
+
},
|
|
2352
|
+
{
|
|
2353
|
+
"$ref": "#/components/parameters/Cursor"
|
|
2354
|
+
},
|
|
2355
|
+
{
|
|
2356
|
+
"name": "status",
|
|
2357
|
+
"in": "query",
|
|
2358
|
+
"schema": {
|
|
2359
|
+
"$ref": "#/components/schemas/HelpdeskConversationStatus"
|
|
2360
|
+
}
|
|
2361
|
+
},
|
|
2362
|
+
{
|
|
2363
|
+
"name": "assignee_user_id",
|
|
2364
|
+
"in": "query",
|
|
2365
|
+
"schema": {
|
|
2366
|
+
"type": "string"
|
|
2367
|
+
},
|
|
2368
|
+
"description": "Only conversations assigned to this user."
|
|
2369
|
+
},
|
|
2370
|
+
{
|
|
2371
|
+
"name": "requester",
|
|
2372
|
+
"in": "query",
|
|
2373
|
+
"schema": {
|
|
2374
|
+
"type": "string"
|
|
2375
|
+
},
|
|
2376
|
+
"description": "Match against visitor name/email."
|
|
2377
|
+
},
|
|
2378
|
+
{
|
|
2379
|
+
"name": "query",
|
|
2380
|
+
"in": "query",
|
|
2381
|
+
"schema": {
|
|
2382
|
+
"type": "string"
|
|
2383
|
+
},
|
|
2384
|
+
"description": "Free-text search query."
|
|
2385
|
+
},
|
|
2386
|
+
{
|
|
2387
|
+
"name": "channels",
|
|
2388
|
+
"in": "query",
|
|
2389
|
+
"schema": {
|
|
2390
|
+
"type": "string"
|
|
2391
|
+
},
|
|
2392
|
+
"description": "Comma-separated channel types (e.g. `widget,whatsapp`)."
|
|
2393
|
+
}
|
|
2394
|
+
],
|
|
2395
|
+
"responses": {
|
|
2396
|
+
"200": {
|
|
2397
|
+
"description": "Conversations page.",
|
|
2398
|
+
"content": {
|
|
2399
|
+
"application/json": {
|
|
2400
|
+
"schema": {
|
|
2401
|
+
"$ref": "#/components/schemas/PaginatedResponse_HelpdeskConversation"
|
|
2402
|
+
}
|
|
2279
2403
|
}
|
|
2280
2404
|
}
|
|
2405
|
+
},
|
|
2406
|
+
"default": {
|
|
2407
|
+
"$ref": "#/components/responses/ApiError"
|
|
2281
2408
|
}
|
|
2282
|
-
}
|
|
2409
|
+
}
|
|
2410
|
+
}
|
|
2411
|
+
},
|
|
2412
|
+
"/api/v1/helpdesk/conversations/{id}": {
|
|
2413
|
+
"parameters": [
|
|
2414
|
+
{
|
|
2415
|
+
"$ref": "#/components/parameters/Id"
|
|
2416
|
+
}
|
|
2417
|
+
],
|
|
2418
|
+
"get": {
|
|
2419
|
+
"tags": [
|
|
2420
|
+
"Helpdesk"
|
|
2421
|
+
],
|
|
2422
|
+
"operationId": "getHelpdeskConversation",
|
|
2423
|
+
"summary": "Get a helpdesk conversation",
|
|
2283
2424
|
"responses": {
|
|
2284
2425
|
"200": {
|
|
2285
|
-
"description": "
|
|
2426
|
+
"description": "Conversation.",
|
|
2286
2427
|
"content": {
|
|
2287
2428
|
"application/json": {
|
|
2288
2429
|
"schema": {
|
|
2289
|
-
"$ref": "#/components/schemas/
|
|
2430
|
+
"$ref": "#/components/schemas/ApiResponse_HelpdeskConversation"
|
|
2290
2431
|
}
|
|
2291
2432
|
}
|
|
2292
2433
|
}
|
|
@@ -2296,20 +2437,30 @@
|
|
|
2296
2437
|
}
|
|
2297
2438
|
}
|
|
2298
2439
|
},
|
|
2299
|
-
"
|
|
2440
|
+
"patch": {
|
|
2300
2441
|
"tags": [
|
|
2301
|
-
"
|
|
2442
|
+
"Helpdesk"
|
|
2302
2443
|
],
|
|
2303
|
-
"operationId": "
|
|
2304
|
-
"summary": "
|
|
2305
|
-
"description": "
|
|
2444
|
+
"operationId": "updateHelpdeskConversation",
|
|
2445
|
+
"summary": "Update a conversation's status or assignee",
|
|
2446
|
+
"description": "Set `status` and/or `assignee_user_id` (`null` unassigns). At least one field is required. Capability-scoped tokens must send `Idempotency-Key` and `X-Capability-Confirmation` headers on this route; API keys with legacy scopes may omit them.",
|
|
2447
|
+
"requestBody": {
|
|
2448
|
+
"required": true,
|
|
2449
|
+
"content": {
|
|
2450
|
+
"application/json": {
|
|
2451
|
+
"schema": {
|
|
2452
|
+
"$ref": "#/components/schemas/UpdateHelpdeskConversationInput"
|
|
2453
|
+
}
|
|
2454
|
+
}
|
|
2455
|
+
}
|
|
2456
|
+
},
|
|
2306
2457
|
"responses": {
|
|
2307
2458
|
"200": {
|
|
2308
|
-
"description": "
|
|
2459
|
+
"description": "Update result.",
|
|
2309
2460
|
"content": {
|
|
2310
2461
|
"application/json": {
|
|
2311
2462
|
"schema": {
|
|
2312
|
-
"$ref": "#/components/schemas/
|
|
2463
|
+
"$ref": "#/components/schemas/ApiResponse_HelpdeskConversationUpdateResult"
|
|
2313
2464
|
}
|
|
2314
2465
|
}
|
|
2315
2466
|
}
|
|
@@ -2320,7 +2471,7 @@
|
|
|
2320
2471
|
}
|
|
2321
2472
|
}
|
|
2322
2473
|
},
|
|
2323
|
-
"/api/v1/
|
|
2474
|
+
"/api/v1/helpdesk/conversations/{id}/messages": {
|
|
2324
2475
|
"parameters": [
|
|
2325
2476
|
{
|
|
2326
2477
|
"$ref": "#/components/parameters/Id"
|
|
@@ -2328,10 +2479,10 @@
|
|
|
2328
2479
|
],
|
|
2329
2480
|
"get": {
|
|
2330
2481
|
"tags": [
|
|
2331
|
-
"
|
|
2482
|
+
"Helpdesk"
|
|
2332
2483
|
],
|
|
2333
|
-
"operationId": "
|
|
2334
|
-
"summary": "List
|
|
2484
|
+
"operationId": "listHelpdeskConversationMessages",
|
|
2485
|
+
"summary": "List conversation messages",
|
|
2335
2486
|
"parameters": [
|
|
2336
2487
|
{
|
|
2337
2488
|
"name": "limit",
|
|
@@ -2339,47 +2490,30 @@
|
|
|
2339
2490
|
"schema": {
|
|
2340
2491
|
"type": "integer",
|
|
2341
2492
|
"minimum": 1,
|
|
2342
|
-
"maximum":
|
|
2493
|
+
"maximum": 50
|
|
2343
2494
|
}
|
|
2495
|
+
},
|
|
2496
|
+
{
|
|
2497
|
+
"$ref": "#/components/parameters/Cursor"
|
|
2344
2498
|
}
|
|
2345
2499
|
],
|
|
2346
2500
|
"responses": {
|
|
2347
2501
|
"200": {
|
|
2348
|
-
"description": "
|
|
2502
|
+
"description": "Messages page.",
|
|
2349
2503
|
"content": {
|
|
2350
2504
|
"application/json": {
|
|
2351
2505
|
"schema": {
|
|
2352
|
-
"$ref": "#/components/schemas/
|
|
2506
|
+
"$ref": "#/components/schemas/PaginatedResponse_HelpdeskMessage"
|
|
2353
2507
|
}
|
|
2354
2508
|
}
|
|
2355
2509
|
}
|
|
2356
2510
|
},
|
|
2357
|
-
"
|
|
2358
|
-
"
|
|
2359
|
-
}
|
|
2360
|
-
}
|
|
2361
|
-
}
|
|
2362
|
-
},
|
|
2363
|
-
"/api/v1/webhooks/{id}/test": {
|
|
2364
|
-
"parameters": [
|
|
2365
|
-
{
|
|
2366
|
-
"$ref": "#/components/parameters/Id"
|
|
2367
|
-
}
|
|
2368
|
-
],
|
|
2369
|
-
"post": {
|
|
2370
|
-
"tags": [
|
|
2371
|
-
"Webhooks"
|
|
2372
|
-
],
|
|
2373
|
-
"operationId": "testWebhook",
|
|
2374
|
-
"summary": "Queue a test delivery",
|
|
2375
|
-
"description": "Queues a signed `test.ping` delivery to the endpoint.",
|
|
2376
|
-
"responses": {
|
|
2377
|
-
"202": {
|
|
2378
|
-
"description": "Test delivery queued.",
|
|
2511
|
+
"404": {
|
|
2512
|
+
"description": "Conversation not found.",
|
|
2379
2513
|
"content": {
|
|
2380
2514
|
"application/json": {
|
|
2381
2515
|
"schema": {
|
|
2382
|
-
"$ref": "#/components/schemas/
|
|
2516
|
+
"$ref": "#/components/schemas/ApiError"
|
|
2383
2517
|
}
|
|
2384
2518
|
}
|
|
2385
2519
|
}
|
|
@@ -2390,31 +2524,31 @@
|
|
|
2390
2524
|
}
|
|
2391
2525
|
}
|
|
2392
2526
|
},
|
|
2393
|
-
"/api/v1/
|
|
2527
|
+
"/api/v1/helpdesk/replies": {
|
|
2394
2528
|
"post": {
|
|
2395
2529
|
"tags": [
|
|
2396
|
-
"
|
|
2530
|
+
"Helpdesk"
|
|
2397
2531
|
],
|
|
2398
|
-
"operationId": "
|
|
2399
|
-
"summary": "
|
|
2400
|
-
"description": "
|
|
2532
|
+
"operationId": "createHelpdeskReply",
|
|
2533
|
+
"summary": "Send an operator reply or internal note",
|
|
2534
|
+
"description": "Send an `Idempotency-Key` header so retried requests do not create duplicate messages — it is required for capability-scoped tokens (together with `X-Capability-Confirmation`).",
|
|
2401
2535
|
"requestBody": {
|
|
2402
2536
|
"required": true,
|
|
2403
2537
|
"content": {
|
|
2404
2538
|
"application/json": {
|
|
2405
2539
|
"schema": {
|
|
2406
|
-
"$ref": "#/components/schemas/
|
|
2540
|
+
"$ref": "#/components/schemas/CreateHelpdeskReplyInput"
|
|
2407
2541
|
}
|
|
2408
2542
|
}
|
|
2409
2543
|
}
|
|
2410
2544
|
},
|
|
2411
2545
|
"responses": {
|
|
2412
|
-
"
|
|
2413
|
-
"description": "
|
|
2546
|
+
"201": {
|
|
2547
|
+
"description": "Created reply reference.",
|
|
2414
2548
|
"content": {
|
|
2415
2549
|
"application/json": {
|
|
2416
2550
|
"schema": {
|
|
2417
|
-
"$ref": "#/components/schemas/
|
|
2551
|
+
"$ref": "#/components/schemas/ApiResponse_HelpdeskReplyCreateResult"
|
|
2418
2552
|
}
|
|
2419
2553
|
}
|
|
2420
2554
|
}
|
|
@@ -2425,31 +2559,53 @@
|
|
|
2425
2559
|
}
|
|
2426
2560
|
}
|
|
2427
2561
|
},
|
|
2428
|
-
"/api/v1/
|
|
2562
|
+
"/api/v1/webhooks": {
|
|
2563
|
+
"get": {
|
|
2564
|
+
"tags": [
|
|
2565
|
+
"Webhooks"
|
|
2566
|
+
],
|
|
2567
|
+
"operationId": "listWebhooks",
|
|
2568
|
+
"summary": "List webhook endpoints",
|
|
2569
|
+
"responses": {
|
|
2570
|
+
"200": {
|
|
2571
|
+
"description": "Webhook endpoints.",
|
|
2572
|
+
"content": {
|
|
2573
|
+
"application/json": {
|
|
2574
|
+
"schema": {
|
|
2575
|
+
"$ref": "#/components/schemas/ApiResponse_WebhookEndpointArray"
|
|
2576
|
+
}
|
|
2577
|
+
}
|
|
2578
|
+
}
|
|
2579
|
+
},
|
|
2580
|
+
"default": {
|
|
2581
|
+
"$ref": "#/components/responses/ApiError"
|
|
2582
|
+
}
|
|
2583
|
+
}
|
|
2584
|
+
},
|
|
2429
2585
|
"post": {
|
|
2430
2586
|
"tags": [
|
|
2431
|
-
"
|
|
2587
|
+
"Webhooks"
|
|
2432
2588
|
],
|
|
2433
|
-
"operationId": "
|
|
2434
|
-
"summary": "
|
|
2435
|
-
"description": "
|
|
2589
|
+
"operationId": "createWebhook",
|
|
2590
|
+
"summary": "Create a webhook endpoint",
|
|
2591
|
+
"description": "The response's `data.secret` contains the signing secret EXACTLY ONCE — it can never be retrieved again, so store it securely immediately. An idempotent replay (same `Idempotency-Key`) returns the existing endpoint WITHOUT `secret`. Deliveries are HTTP POSTs signed with `X-Medal-Signature: sha256=<base64(HMAC-SHA256(\"{timestamp}.{rawBody}\", secret))>` plus `X-Medal-Timestamp`, `X-Medal-Event`, and `X-Medal-Delivery-Id` / `Idempotency-Key` headers.",
|
|
2436
2592
|
"requestBody": {
|
|
2437
2593
|
"required": true,
|
|
2438
2594
|
"content": {
|
|
2439
2595
|
"application/json": {
|
|
2440
2596
|
"schema": {
|
|
2441
|
-
"$ref": "#/components/schemas/
|
|
2597
|
+
"$ref": "#/components/schemas/CreateWebhookInput"
|
|
2442
2598
|
}
|
|
2443
2599
|
}
|
|
2444
2600
|
}
|
|
2445
2601
|
},
|
|
2446
2602
|
"responses": {
|
|
2447
2603
|
"201": {
|
|
2448
|
-
"description": "
|
|
2604
|
+
"description": "Created endpoint, including the one-time `secret`.",
|
|
2449
2605
|
"content": {
|
|
2450
2606
|
"application/json": {
|
|
2451
2607
|
"schema": {
|
|
2452
|
-
"$ref": "#/components/schemas/
|
|
2608
|
+
"$ref": "#/components/schemas/ApiResponse_WebhookEndpoint"
|
|
2453
2609
|
}
|
|
2454
2610
|
}
|
|
2455
2611
|
}
|
|
@@ -2458,24 +2614,249 @@
|
|
|
2458
2614
|
"$ref": "#/components/responses/ApiError"
|
|
2459
2615
|
}
|
|
2460
2616
|
}
|
|
2461
|
-
}
|
|
2617
|
+
}
|
|
2618
|
+
},
|
|
2619
|
+
"/api/v1/webhooks/{id}": {
|
|
2620
|
+
"parameters": [
|
|
2621
|
+
{
|
|
2622
|
+
"$ref": "#/components/parameters/Id"
|
|
2623
|
+
}
|
|
2624
|
+
],
|
|
2462
2625
|
"get": {
|
|
2463
2626
|
"tags": [
|
|
2464
|
-
"
|
|
2627
|
+
"Webhooks"
|
|
2465
2628
|
],
|
|
2466
|
-
"operationId": "
|
|
2467
|
-
"summary": "
|
|
2468
|
-
"
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
"
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
}
|
|
2478
|
-
|
|
2629
|
+
"operationId": "getWebhook",
|
|
2630
|
+
"summary": "Get a webhook endpoint",
|
|
2631
|
+
"responses": {
|
|
2632
|
+
"200": {
|
|
2633
|
+
"description": "Webhook endpoint.",
|
|
2634
|
+
"content": {
|
|
2635
|
+
"application/json": {
|
|
2636
|
+
"schema": {
|
|
2637
|
+
"$ref": "#/components/schemas/ApiResponse_WebhookEndpoint"
|
|
2638
|
+
}
|
|
2639
|
+
}
|
|
2640
|
+
}
|
|
2641
|
+
},
|
|
2642
|
+
"default": {
|
|
2643
|
+
"$ref": "#/components/responses/ApiError"
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2646
|
+
},
|
|
2647
|
+
"patch": {
|
|
2648
|
+
"tags": [
|
|
2649
|
+
"Webhooks"
|
|
2650
|
+
],
|
|
2651
|
+
"operationId": "updateWebhook",
|
|
2652
|
+
"summary": "Update a webhook endpoint",
|
|
2653
|
+
"description": "Only provided fields change. Pass `null` for `channels` or `channel_connection_ids` to clear that filter.",
|
|
2654
|
+
"requestBody": {
|
|
2655
|
+
"required": true,
|
|
2656
|
+
"content": {
|
|
2657
|
+
"application/json": {
|
|
2658
|
+
"schema": {
|
|
2659
|
+
"$ref": "#/components/schemas/UpdateWebhookInput"
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
}
|
|
2663
|
+
},
|
|
2664
|
+
"responses": {
|
|
2665
|
+
"200": {
|
|
2666
|
+
"description": "Updated endpoint.",
|
|
2667
|
+
"content": {
|
|
2668
|
+
"application/json": {
|
|
2669
|
+
"schema": {
|
|
2670
|
+
"$ref": "#/components/schemas/ApiResponse_WebhookEndpoint"
|
|
2671
|
+
}
|
|
2672
|
+
}
|
|
2673
|
+
}
|
|
2674
|
+
},
|
|
2675
|
+
"default": {
|
|
2676
|
+
"$ref": "#/components/responses/ApiError"
|
|
2677
|
+
}
|
|
2678
|
+
}
|
|
2679
|
+
},
|
|
2680
|
+
"delete": {
|
|
2681
|
+
"tags": [
|
|
2682
|
+
"Webhooks"
|
|
2683
|
+
],
|
|
2684
|
+
"operationId": "deleteWebhook",
|
|
2685
|
+
"summary": "Delete a webhook endpoint",
|
|
2686
|
+
"description": "Permanently deletes the endpoint and stops all outbound deliveries. Capability-scoped tokens must send `Idempotency-Key` and `X-Capability-Confirmation` headers on this route; API keys with legacy scopes may omit them.",
|
|
2687
|
+
"responses": {
|
|
2688
|
+
"200": {
|
|
2689
|
+
"description": "Delete result.",
|
|
2690
|
+
"content": {
|
|
2691
|
+
"application/json": {
|
|
2692
|
+
"schema": {
|
|
2693
|
+
"$ref": "#/components/schemas/ApiResponse_WebhookDeleteResult"
|
|
2694
|
+
}
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
},
|
|
2698
|
+
"default": {
|
|
2699
|
+
"$ref": "#/components/responses/ApiError"
|
|
2700
|
+
}
|
|
2701
|
+
}
|
|
2702
|
+
}
|
|
2703
|
+
},
|
|
2704
|
+
"/api/v1/webhooks/{id}/deliveries": {
|
|
2705
|
+
"parameters": [
|
|
2706
|
+
{
|
|
2707
|
+
"$ref": "#/components/parameters/Id"
|
|
2708
|
+
}
|
|
2709
|
+
],
|
|
2710
|
+
"get": {
|
|
2711
|
+
"tags": [
|
|
2712
|
+
"Webhooks"
|
|
2713
|
+
],
|
|
2714
|
+
"operationId": "listWebhookDeliveries",
|
|
2715
|
+
"summary": "List recent deliveries",
|
|
2716
|
+
"parameters": [
|
|
2717
|
+
{
|
|
2718
|
+
"name": "limit",
|
|
2719
|
+
"in": "query",
|
|
2720
|
+
"schema": {
|
|
2721
|
+
"type": "integer",
|
|
2722
|
+
"minimum": 1,
|
|
2723
|
+
"maximum": 100
|
|
2724
|
+
}
|
|
2725
|
+
}
|
|
2726
|
+
],
|
|
2727
|
+
"responses": {
|
|
2728
|
+
"200": {
|
|
2729
|
+
"description": "Recent deliveries, most recent first.",
|
|
2730
|
+
"content": {
|
|
2731
|
+
"application/json": {
|
|
2732
|
+
"schema": {
|
|
2733
|
+
"$ref": "#/components/schemas/ApiResponse_WebhookDeliveryArray"
|
|
2734
|
+
}
|
|
2735
|
+
}
|
|
2736
|
+
}
|
|
2737
|
+
},
|
|
2738
|
+
"default": {
|
|
2739
|
+
"$ref": "#/components/responses/ApiError"
|
|
2740
|
+
}
|
|
2741
|
+
}
|
|
2742
|
+
}
|
|
2743
|
+
},
|
|
2744
|
+
"/api/v1/webhooks/{id}/test": {
|
|
2745
|
+
"parameters": [
|
|
2746
|
+
{
|
|
2747
|
+
"$ref": "#/components/parameters/Id"
|
|
2748
|
+
}
|
|
2749
|
+
],
|
|
2750
|
+
"post": {
|
|
2751
|
+
"tags": [
|
|
2752
|
+
"Webhooks"
|
|
2753
|
+
],
|
|
2754
|
+
"operationId": "testWebhook",
|
|
2755
|
+
"summary": "Queue a test delivery",
|
|
2756
|
+
"description": "Queues a signed `test.ping` delivery to the endpoint.",
|
|
2757
|
+
"responses": {
|
|
2758
|
+
"202": {
|
|
2759
|
+
"description": "Test delivery queued.",
|
|
2760
|
+
"content": {
|
|
2761
|
+
"application/json": {
|
|
2762
|
+
"schema": {
|
|
2763
|
+
"$ref": "#/components/schemas/ApiResponse_WebhookTestResult"
|
|
2764
|
+
}
|
|
2765
|
+
}
|
|
2766
|
+
}
|
|
2767
|
+
},
|
|
2768
|
+
"default": {
|
|
2769
|
+
"$ref": "#/components/responses/ApiError"
|
|
2770
|
+
}
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2773
|
+
},
|
|
2774
|
+
"/api/v1/capability-confirmations": {
|
|
2775
|
+
"post": {
|
|
2776
|
+
"tags": [
|
|
2777
|
+
"Capabilities"
|
|
2778
|
+
],
|
|
2779
|
+
"operationId": "issueCapabilityConfirmation",
|
|
2780
|
+
"summary": "Issue a capability confirmation token",
|
|
2781
|
+
"description": "Mints a short-lived `X-Capability-Confirmation` token for one pending write. Confirmable write routes require BOTH `Idempotency-Key` and `X-Capability-Confirmation` when the credential holds the capability scope directly; API keys with legacy scopes are exempt. The token is bound to the workspace, auth subject, method, path, required scopes and idempotency key, and expires within 15 minutes. `user_approved: true` asserts that a human on the caller's side approved this exact action.",
|
|
2782
|
+
"requestBody": {
|
|
2783
|
+
"required": true,
|
|
2784
|
+
"content": {
|
|
2785
|
+
"application/json": {
|
|
2786
|
+
"schema": {
|
|
2787
|
+
"$ref": "#/components/schemas/IssueCapabilityConfirmationInput"
|
|
2788
|
+
}
|
|
2789
|
+
}
|
|
2790
|
+
}
|
|
2791
|
+
},
|
|
2792
|
+
"responses": {
|
|
2793
|
+
"200": {
|
|
2794
|
+
"description": "Minted confirmation token.",
|
|
2795
|
+
"content": {
|
|
2796
|
+
"application/json": {
|
|
2797
|
+
"schema": {
|
|
2798
|
+
"$ref": "#/components/schemas/ApiResponse_CapabilityConfirmation"
|
|
2799
|
+
}
|
|
2800
|
+
}
|
|
2801
|
+
}
|
|
2802
|
+
},
|
|
2803
|
+
"default": {
|
|
2804
|
+
"$ref": "#/components/responses/ApiError"
|
|
2805
|
+
}
|
|
2806
|
+
}
|
|
2807
|
+
}
|
|
2808
|
+
},
|
|
2809
|
+
"/api/v1/channels/connect-links": {
|
|
2810
|
+
"post": {
|
|
2811
|
+
"tags": [
|
|
2812
|
+
"Channels"
|
|
2813
|
+
],
|
|
2814
|
+
"operationId": "createChannelConnectLink",
|
|
2815
|
+
"summary": "Mint a hosted connect link",
|
|
2816
|
+
"description": "Mints a single-use hosted connect link that lets an external person (no Medal account required) attach a channel account (e.g. `telegram_inbox`) to the workspace's helpdesk. The response's `data.url` contains the one-time link token EXACTLY ONCE — an idempotent replay (same `Idempotency-Key`) returns the link WITHOUT `url`. Requires the `channel.connect.manage` scope; OAuth callers additionally need the workspace `admin` role.",
|
|
2817
|
+
"requestBody": {
|
|
2818
|
+
"required": true,
|
|
2819
|
+
"content": {
|
|
2820
|
+
"application/json": {
|
|
2821
|
+
"schema": {
|
|
2822
|
+
"$ref": "#/components/schemas/CreateConnectLinkInput"
|
|
2823
|
+
}
|
|
2824
|
+
}
|
|
2825
|
+
}
|
|
2826
|
+
},
|
|
2827
|
+
"responses": {
|
|
2828
|
+
"201": {
|
|
2829
|
+
"description": "Minted connect link, including the one-time `url`.",
|
|
2830
|
+
"content": {
|
|
2831
|
+
"application/json": {
|
|
2832
|
+
"schema": {
|
|
2833
|
+
"$ref": "#/components/schemas/ApiResponse_ConnectLinkCreateResult"
|
|
2834
|
+
}
|
|
2835
|
+
}
|
|
2836
|
+
}
|
|
2837
|
+
},
|
|
2838
|
+
"default": {
|
|
2839
|
+
"$ref": "#/components/responses/ApiError"
|
|
2840
|
+
}
|
|
2841
|
+
}
|
|
2842
|
+
},
|
|
2843
|
+
"get": {
|
|
2844
|
+
"tags": [
|
|
2845
|
+
"Channels"
|
|
2846
|
+
],
|
|
2847
|
+
"operationId": "listChannelConnectLinks",
|
|
2848
|
+
"summary": "List connect links",
|
|
2849
|
+
"description": "Link tokens are never returned. Newest first, cursor-paginated. The `channel_type` / `status` filters are applied within each page, so a page may hold fewer than `limit` items while `pagination.has_more` is still true — page off `has_more`, not the item count.",
|
|
2850
|
+
"parameters": [
|
|
2851
|
+
{
|
|
2852
|
+
"name": "limit",
|
|
2853
|
+
"in": "query",
|
|
2854
|
+
"schema": {
|
|
2855
|
+
"type": "integer",
|
|
2856
|
+
"minimum": 1,
|
|
2857
|
+
"maximum": 100
|
|
2858
|
+
},
|
|
2859
|
+
"description": "Page size (default 50, capped at 100)."
|
|
2479
2860
|
},
|
|
2480
2861
|
{
|
|
2481
2862
|
"$ref": "#/components/parameters/Cursor"
|
|
@@ -4401,6 +4782,28 @@
|
|
|
4401
4782
|
"refunded"
|
|
4402
4783
|
]
|
|
4403
4784
|
},
|
|
4785
|
+
"BookingPaymentMode": {
|
|
4786
|
+
"description": "What a booking must have paid before the business honours it: nothing, a reservation captured later, or the full amount up front.",
|
|
4787
|
+
"type": "string",
|
|
4788
|
+
"enum": [
|
|
4789
|
+
"none",
|
|
4790
|
+
"reserve",
|
|
4791
|
+
"prepay"
|
|
4792
|
+
]
|
|
4793
|
+
},
|
|
4794
|
+
"BookingPaymentState": {
|
|
4795
|
+
"description": "The state of one payment attempt, in Medal's vocabulary rather than the wallet's — a Vipps payment stays AUTHORIZED after a capture, so read the øre aggregates to learn what actually moved.",
|
|
4796
|
+
"type": "string",
|
|
4797
|
+
"enum": [
|
|
4798
|
+
"created",
|
|
4799
|
+
"authorized",
|
|
4800
|
+
"captured",
|
|
4801
|
+
"cancelled",
|
|
4802
|
+
"refunded",
|
|
4803
|
+
"failed",
|
|
4804
|
+
"expired"
|
|
4805
|
+
]
|
|
4806
|
+
},
|
|
4404
4807
|
"BookingCreatedVia": {
|
|
4405
4808
|
"type": "string",
|
|
4406
4809
|
"enum": [
|
|
@@ -4429,12 +4832,16 @@
|
|
|
4429
4832
|
"end_ts",
|
|
4430
4833
|
"booked_for_name",
|
|
4431
4834
|
"booked_for_birth_year",
|
|
4835
|
+
"booked_for_person_id",
|
|
4836
|
+
"event_id",
|
|
4837
|
+
"event_order",
|
|
4432
4838
|
"party_sequence_id",
|
|
4433
4839
|
"status",
|
|
4434
4840
|
"cancelled_by",
|
|
4435
4841
|
"cancel_reason",
|
|
4436
4842
|
"rescheduled_from_id",
|
|
4437
4843
|
"payment_status",
|
|
4844
|
+
"payment_mode",
|
|
4438
4845
|
"amount_ore",
|
|
4439
4846
|
"notes",
|
|
4440
4847
|
"internal_notes",
|
|
@@ -4491,21 +4898,42 @@
|
|
|
4491
4898
|
"null"
|
|
4492
4899
|
]
|
|
4493
4900
|
},
|
|
4494
|
-
"
|
|
4495
|
-
"description": "
|
|
4901
|
+
"booked_for_person_id": {
|
|
4902
|
+
"description": "The ContactPerson this booking was made for, if any.",
|
|
4496
4903
|
"type": [
|
|
4497
4904
|
"string",
|
|
4498
4905
|
"null"
|
|
4499
4906
|
]
|
|
4500
4907
|
},
|
|
4501
|
-
"
|
|
4502
|
-
"
|
|
4908
|
+
"event_id": {
|
|
4909
|
+
"description": "The BookingEvent this booking is a registration for, if any.",
|
|
4910
|
+
"type": [
|
|
4911
|
+
"string",
|
|
4912
|
+
"null"
|
|
4913
|
+
]
|
|
4503
4914
|
},
|
|
4504
|
-
"
|
|
4505
|
-
"
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4915
|
+
"event_order": {
|
|
4916
|
+
"description": "Position of this booking within its event's registrations, if any.",
|
|
4917
|
+
"type": [
|
|
4918
|
+
"integer",
|
|
4919
|
+
"null"
|
|
4920
|
+
]
|
|
4921
|
+
},
|
|
4922
|
+
"party_sequence_id": {
|
|
4923
|
+
"description": "Shared by every booking created in the same party request.",
|
|
4924
|
+
"type": [
|
|
4925
|
+
"string",
|
|
4926
|
+
"null"
|
|
4927
|
+
]
|
|
4928
|
+
},
|
|
4929
|
+
"status": {
|
|
4930
|
+
"$ref": "#/components/schemas/BookingStatus"
|
|
4931
|
+
},
|
|
4932
|
+
"cancelled_by": {
|
|
4933
|
+
"oneOf": [
|
|
4934
|
+
{
|
|
4935
|
+
"$ref": "#/components/schemas/BookingCancelledBy"
|
|
4936
|
+
},
|
|
4509
4937
|
{
|
|
4510
4938
|
"type": "null"
|
|
4511
4939
|
}
|
|
@@ -4527,6 +4955,10 @@
|
|
|
4527
4955
|
"payment_status": {
|
|
4528
4956
|
"$ref": "#/components/schemas/BookingPaymentStatus"
|
|
4529
4957
|
},
|
|
4958
|
+
"payment_mode": {
|
|
4959
|
+
"description": "What this booking required when it was made — frozen at creation. `payment_status: none` cannot tell \"owes nothing\" from \"has not paid yet\"; this can.",
|
|
4960
|
+
"$ref": "#/components/schemas/BookingPaymentMode"
|
|
4961
|
+
},
|
|
4530
4962
|
"amount_ore": {
|
|
4531
4963
|
"description": "Price in integer øre. Never a float and never kroner.",
|
|
4532
4964
|
"type": [
|
|
@@ -4588,6 +5020,7 @@
|
|
|
4588
5020
|
"weekend_surcharge_pct",
|
|
4589
5021
|
"resource_requirements",
|
|
4590
5022
|
"bookable_online",
|
|
5023
|
+
"payment",
|
|
4591
5024
|
"max_per_booking",
|
|
4592
5025
|
"color",
|
|
4593
5026
|
"sort_order",
|
|
@@ -4658,6 +5091,17 @@
|
|
|
4658
5091
|
"bookable_online": {
|
|
4659
5092
|
"type": "boolean"
|
|
4660
5093
|
},
|
|
5094
|
+
"payment": {
|
|
5095
|
+
"description": "Per-service payment requirement. `null` means no override — the workspace rule decides.",
|
|
5096
|
+
"oneOf": [
|
|
5097
|
+
{
|
|
5098
|
+
"$ref": "#/components/schemas/BookingPaymentMode"
|
|
5099
|
+
},
|
|
5100
|
+
{
|
|
5101
|
+
"type": "null"
|
|
5102
|
+
}
|
|
5103
|
+
]
|
|
5104
|
+
},
|
|
4661
5105
|
"max_per_booking": {
|
|
4662
5106
|
"type": [
|
|
4663
5107
|
"integer",
|
|
@@ -4899,6 +5343,10 @@
|
|
|
4899
5343
|
"type": "integer",
|
|
4900
5344
|
"minimum": 1900,
|
|
4901
5345
|
"maximum": 2200
|
|
5346
|
+
},
|
|
5347
|
+
"booked_for_person_id": {
|
|
5348
|
+
"description": "Book this line on behalf of a ContactPerson rather than the contact.",
|
|
5349
|
+
"type": "string"
|
|
4902
5350
|
}
|
|
4903
5351
|
}
|
|
4904
5352
|
},
|
|
@@ -5022,6 +5470,7 @@
|
|
|
5022
5470
|
"party_sequence_id",
|
|
5023
5471
|
"amount_ore",
|
|
5024
5472
|
"payment_status",
|
|
5473
|
+
"payment_mode",
|
|
5025
5474
|
"time_zone",
|
|
5026
5475
|
"cancel_window_hours",
|
|
5027
5476
|
"reschedule_window_hours",
|
|
@@ -5137,6 +5586,10 @@
|
|
|
5137
5586
|
}
|
|
5138
5587
|
]
|
|
5139
5588
|
},
|
|
5589
|
+
"payment_mode": {
|
|
5590
|
+
"description": "What this booking requires — what a manage page checks before offering «Betal nå».",
|
|
5591
|
+
"$ref": "#/components/schemas/BookingPaymentMode"
|
|
5592
|
+
},
|
|
5140
5593
|
"time_zone": {
|
|
5141
5594
|
"description": "IANA zone the booking's local times should be rendered in.",
|
|
5142
5595
|
"type": [
|
|
@@ -5228,6 +5681,169 @@
|
|
|
5228
5681
|
}
|
|
5229
5682
|
}
|
|
5230
5683
|
},
|
|
5684
|
+
"StartBookingPaymentInput": {
|
|
5685
|
+
"description": "Body for `startBookingPayment` and `startManageBookingPayment`.",
|
|
5686
|
+
"type": "object",
|
|
5687
|
+
"required": [
|
|
5688
|
+
"return_url",
|
|
5689
|
+
"terms_accepted"
|
|
5690
|
+
],
|
|
5691
|
+
"properties": {
|
|
5692
|
+
"return_url": {
|
|
5693
|
+
"description": "Where the wallet returns the customer. Must be a URL one of this workspace's own sites vouches for; anything else answers 422.",
|
|
5694
|
+
"type": "string",
|
|
5695
|
+
"minLength": 1,
|
|
5696
|
+
"maxLength": 2048
|
|
5697
|
+
},
|
|
5698
|
+
"terms_accepted": {
|
|
5699
|
+
"description": "Must be literally `true`. The customer has to actively accept the merchant's terms BEFORE a payment is initiated, so omitting it or sending `false` is a 400 and leaves no payment behind.",
|
|
5700
|
+
"const": true,
|
|
5701
|
+
"type": "boolean"
|
|
5702
|
+
},
|
|
5703
|
+
"terms_version": {
|
|
5704
|
+
"description": "The caller's own version label for the terms that were accepted.",
|
|
5705
|
+
"type": "string",
|
|
5706
|
+
"minLength": 1,
|
|
5707
|
+
"maxLength": 64
|
|
5708
|
+
},
|
|
5709
|
+
"terms_text": {
|
|
5710
|
+
"description": "The exact text that was accepted, stored with the consent record.",
|
|
5711
|
+
"type": "string",
|
|
5712
|
+
"maxLength": 2000
|
|
5713
|
+
}
|
|
5714
|
+
}
|
|
5715
|
+
},
|
|
5716
|
+
"BookingPaymentStart": {
|
|
5717
|
+
"description": "The result of starting a payment. `redirect_url` is handed over here and nowhere else.",
|
|
5718
|
+
"type": "object",
|
|
5719
|
+
"required": [
|
|
5720
|
+
"reference",
|
|
5721
|
+
"redirect_url",
|
|
5722
|
+
"state"
|
|
5723
|
+
],
|
|
5724
|
+
"properties": {
|
|
5725
|
+
"reference": {
|
|
5726
|
+
"description": "The wallet reference for this attempt.",
|
|
5727
|
+
"type": "string"
|
|
5728
|
+
},
|
|
5729
|
+
"redirect_url": {
|
|
5730
|
+
"description": "Send the customer here UNCHANGED — hand it to the Vipps Widget SDK. SHOW-ONCE: it is not returned by `getBookingPayment`, and the payment behind it expires after ten minutes.",
|
|
5731
|
+
"type": "string"
|
|
5732
|
+
},
|
|
5733
|
+
"state": {
|
|
5734
|
+
"$ref": "#/components/schemas/BookingPaymentState"
|
|
5735
|
+
}
|
|
5736
|
+
}
|
|
5737
|
+
},
|
|
5738
|
+
"BookingPayment": {
|
|
5739
|
+
"description": "One payment attempt on a booking. Money is integer øre, and the four aggregates are numbers rather than nulls — \"nothing captured\" is `0`. `redirect_url`, the wallet's own refusal text and the trace id are deliberately absent.",
|
|
5740
|
+
"type": "object",
|
|
5741
|
+
"required": [
|
|
5742
|
+
"reference",
|
|
5743
|
+
"provider",
|
|
5744
|
+
"state",
|
|
5745
|
+
"mode",
|
|
5746
|
+
"attempt",
|
|
5747
|
+
"amount_ore",
|
|
5748
|
+
"authorized_ore",
|
|
5749
|
+
"captured_ore",
|
|
5750
|
+
"refunded_ore",
|
|
5751
|
+
"cancelled_ore",
|
|
5752
|
+
"currency",
|
|
5753
|
+
"capture_guaranteed_until",
|
|
5754
|
+
"terms_version",
|
|
5755
|
+
"terms_accepted_at",
|
|
5756
|
+
"failure_code",
|
|
5757
|
+
"created_at",
|
|
5758
|
+
"updated_at"
|
|
5759
|
+
],
|
|
5760
|
+
"properties": {
|
|
5761
|
+
"reference": {
|
|
5762
|
+
"type": "string"
|
|
5763
|
+
},
|
|
5764
|
+
"provider": {
|
|
5765
|
+
"const": "vipps",
|
|
5766
|
+
"type": "string"
|
|
5767
|
+
},
|
|
5768
|
+
"state": {
|
|
5769
|
+
"$ref": "#/components/schemas/BookingPaymentState"
|
|
5770
|
+
},
|
|
5771
|
+
"mode": {
|
|
5772
|
+
"description": "Never `none` — a payment exists only where one was required.",
|
|
5773
|
+
"type": "string",
|
|
5774
|
+
"enum": [
|
|
5775
|
+
"reserve",
|
|
5776
|
+
"prepay"
|
|
5777
|
+
]
|
|
5778
|
+
},
|
|
5779
|
+
"attempt": {
|
|
5780
|
+
"description": "1 for the first attempt on this booking, incrementing per retry.",
|
|
5781
|
+
"type": "integer"
|
|
5782
|
+
},
|
|
5783
|
+
"amount_ore": {
|
|
5784
|
+
"description": "The amount this attempt is for, in integer øre.",
|
|
5785
|
+
"type": "integer"
|
|
5786
|
+
},
|
|
5787
|
+
"authorized_ore": {
|
|
5788
|
+
"type": "integer"
|
|
5789
|
+
},
|
|
5790
|
+
"captured_ore": {
|
|
5791
|
+
"type": "integer"
|
|
5792
|
+
},
|
|
5793
|
+
"refunded_ore": {
|
|
5794
|
+
"type": "integer"
|
|
5795
|
+
},
|
|
5796
|
+
"cancelled_ore": {
|
|
5797
|
+
"type": "integer"
|
|
5798
|
+
},
|
|
5799
|
+
"currency": {
|
|
5800
|
+
"const": "NOK",
|
|
5801
|
+
"type": "string"
|
|
5802
|
+
},
|
|
5803
|
+
"capture_guaranteed_until": {
|
|
5804
|
+
"description": "The last moment a capture is GUARANTEED to succeed. The card behind the wallet may release the reservation afterwards, so a capture past it can fail even though the payment still looks authorized. Null until the customer has approved.",
|
|
5805
|
+
"type": [
|
|
5806
|
+
"string",
|
|
5807
|
+
"null"
|
|
5808
|
+
],
|
|
5809
|
+
"format": "date-time"
|
|
5810
|
+
},
|
|
5811
|
+
"terms_version": {
|
|
5812
|
+
"type": [
|
|
5813
|
+
"string",
|
|
5814
|
+
"null"
|
|
5815
|
+
]
|
|
5816
|
+
},
|
|
5817
|
+
"terms_accepted_at": {
|
|
5818
|
+
"type": [
|
|
5819
|
+
"string",
|
|
5820
|
+
"null"
|
|
5821
|
+
],
|
|
5822
|
+
"format": "date-time"
|
|
5823
|
+
},
|
|
5824
|
+
"failure_code": {
|
|
5825
|
+
"description": "The wallet's numeric error code from the last failed operation — what a caller branches on.",
|
|
5826
|
+
"type": [
|
|
5827
|
+
"string",
|
|
5828
|
+
"null"
|
|
5829
|
+
]
|
|
5830
|
+
},
|
|
5831
|
+
"created_at": {
|
|
5832
|
+
"type": [
|
|
5833
|
+
"string",
|
|
5834
|
+
"null"
|
|
5835
|
+
],
|
|
5836
|
+
"format": "date-time"
|
|
5837
|
+
},
|
|
5838
|
+
"updated_at": {
|
|
5839
|
+
"type": [
|
|
5840
|
+
"string",
|
|
5841
|
+
"null"
|
|
5842
|
+
],
|
|
5843
|
+
"format": "date-time"
|
|
5844
|
+
}
|
|
5845
|
+
}
|
|
5846
|
+
},
|
|
5231
5847
|
"BookingsPagination": {
|
|
5232
5848
|
"description": "Pagination for a bookings page. `truncated` is the extra statement: the underlying read is capped, and when the cap binds there are matching bookings no cursor from this call reaches — narrow the window.",
|
|
5233
5849
|
"type": "object",
|
|
@@ -6450,6 +7066,12 @@
|
|
|
6450
7066
|
"ApiResponse_BookingRescheduleResult": {
|
|
6451
7067
|
"$ref": "#/components/schemas/Envelope_BookingRescheduleResult"
|
|
6452
7068
|
},
|
|
7069
|
+
"ApiResponse_BookingPaymentStart": {
|
|
7070
|
+
"$ref": "#/components/schemas/Envelope_BookingPaymentStart"
|
|
7071
|
+
},
|
|
7072
|
+
"ApiResponse_BookingPayment": {
|
|
7073
|
+
"$ref": "#/components/schemas/Envelope_BookingPayment"
|
|
7074
|
+
},
|
|
6453
7075
|
"ApiResponse_ManageSummary": {
|
|
6454
7076
|
"$ref": "#/components/schemas/Envelope_ManageSummary"
|
|
6455
7077
|
},
|
|
@@ -7033,6 +7655,28 @@
|
|
|
7033
7655
|
}
|
|
7034
7656
|
}
|
|
7035
7657
|
},
|
|
7658
|
+
"Envelope_BookingPaymentStart": {
|
|
7659
|
+
"type": "object",
|
|
7660
|
+
"required": [
|
|
7661
|
+
"data"
|
|
7662
|
+
],
|
|
7663
|
+
"properties": {
|
|
7664
|
+
"data": {
|
|
7665
|
+
"$ref": "#/components/schemas/BookingPaymentStart"
|
|
7666
|
+
}
|
|
7667
|
+
}
|
|
7668
|
+
},
|
|
7669
|
+
"Envelope_BookingPayment": {
|
|
7670
|
+
"type": "object",
|
|
7671
|
+
"required": [
|
|
7672
|
+
"data"
|
|
7673
|
+
],
|
|
7674
|
+
"properties": {
|
|
7675
|
+
"data": {
|
|
7676
|
+
"$ref": "#/components/schemas/BookingPayment"
|
|
7677
|
+
}
|
|
7678
|
+
}
|
|
7679
|
+
},
|
|
7036
7680
|
"Envelope_ManageSummary": {
|
|
7037
7681
|
"type": "object",
|
|
7038
7682
|
"required": [
|
|
@@ -7145,6 +7789,68 @@
|
|
|
7145
7789
|
}
|
|
7146
7790
|
}
|
|
7147
7791
|
},
|
|
7792
|
+
"PortalPerson": {
|
|
7793
|
+
"description": "A person the contact books for — a child, a pet — with no login of its own.",
|
|
7794
|
+
"type": "object",
|
|
7795
|
+
"required": [
|
|
7796
|
+
"person_id",
|
|
7797
|
+
"name",
|
|
7798
|
+
"birth_year",
|
|
7799
|
+
"relation_type",
|
|
7800
|
+
"relation_label",
|
|
7801
|
+
"notes",
|
|
7802
|
+
"active"
|
|
7803
|
+
],
|
|
7804
|
+
"properties": {
|
|
7805
|
+
"person_id": {
|
|
7806
|
+
"type": "string"
|
|
7807
|
+
},
|
|
7808
|
+
"name": {
|
|
7809
|
+
"type": "string"
|
|
7810
|
+
},
|
|
7811
|
+
"birth_year": {
|
|
7812
|
+
"type": [
|
|
7813
|
+
"integer",
|
|
7814
|
+
"null"
|
|
7815
|
+
]
|
|
7816
|
+
},
|
|
7817
|
+
"relation_type": {
|
|
7818
|
+
"$ref": "#/components/schemas/RelationType"
|
|
7819
|
+
},
|
|
7820
|
+
"relation_label": {
|
|
7821
|
+
"type": [
|
|
7822
|
+
"string",
|
|
7823
|
+
"null"
|
|
7824
|
+
]
|
|
7825
|
+
},
|
|
7826
|
+
"notes": {
|
|
7827
|
+
"type": [
|
|
7828
|
+
"string",
|
|
7829
|
+
"null"
|
|
7830
|
+
]
|
|
7831
|
+
},
|
|
7832
|
+
"active": {
|
|
7833
|
+
"type": "boolean",
|
|
7834
|
+
"description": "False for a person the customer removed or that was promoted to its own contact; `me` returns active persons only, the export returns all."
|
|
7835
|
+
}
|
|
7836
|
+
}
|
|
7837
|
+
},
|
|
7838
|
+
"PortalLabels": {
|
|
7839
|
+
"description": "The workspace's own words for the person concept, e.g. `\"Barn\"`.",
|
|
7840
|
+
"type": "object",
|
|
7841
|
+
"required": [
|
|
7842
|
+
"person",
|
|
7843
|
+
"persons"
|
|
7844
|
+
],
|
|
7845
|
+
"properties": {
|
|
7846
|
+
"person": {
|
|
7847
|
+
"type": "string"
|
|
7848
|
+
},
|
|
7849
|
+
"persons": {
|
|
7850
|
+
"type": "string"
|
|
7851
|
+
}
|
|
7852
|
+
}
|
|
7853
|
+
},
|
|
7148
7854
|
"PortalProfile": {
|
|
7149
7855
|
"type": "object",
|
|
7150
7856
|
"required": [
|
|
@@ -7154,6 +7860,8 @@
|
|
|
7154
7860
|
"last_name",
|
|
7155
7861
|
"phone",
|
|
7156
7862
|
"family",
|
|
7863
|
+
"persons",
|
|
7864
|
+
"labels",
|
|
7157
7865
|
"marketing_consent",
|
|
7158
7866
|
"created_at"
|
|
7159
7867
|
],
|
|
@@ -7188,6 +7896,15 @@
|
|
|
7188
7896
|
"$ref": "#/components/schemas/PortalFamilyMember"
|
|
7189
7897
|
}
|
|
7190
7898
|
},
|
|
7899
|
+
"persons": {
|
|
7900
|
+
"type": "array",
|
|
7901
|
+
"items": {
|
|
7902
|
+
"$ref": "#/components/schemas/PortalPerson"
|
|
7903
|
+
}
|
|
7904
|
+
},
|
|
7905
|
+
"labels": {
|
|
7906
|
+
"$ref": "#/components/schemas/PortalLabels"
|
|
7907
|
+
},
|
|
7191
7908
|
"marketing_consent": {
|
|
7192
7909
|
"type": "boolean"
|
|
7193
7910
|
},
|
|
@@ -7370,6 +8087,52 @@
|
|
|
7370
8087
|
}
|
|
7371
8088
|
}
|
|
7372
8089
|
},
|
|
8090
|
+
"PortalExportRelation": {
|
|
8091
|
+
"description": "A relation the exporting contact is a party to; only the counterpart's display name is exposed.",
|
|
8092
|
+
"type": "object",
|
|
8093
|
+
"required": [
|
|
8094
|
+
"direction",
|
|
8095
|
+
"type",
|
|
8096
|
+
"custom_label",
|
|
8097
|
+
"since",
|
|
8098
|
+
"note",
|
|
8099
|
+
"counterpart_name"
|
|
8100
|
+
],
|
|
8101
|
+
"properties": {
|
|
8102
|
+
"direction": {
|
|
8103
|
+
"type": "string",
|
|
8104
|
+
"enum": [
|
|
8105
|
+
"outgoing",
|
|
8106
|
+
"incoming"
|
|
8107
|
+
]
|
|
8108
|
+
},
|
|
8109
|
+
"type": {
|
|
8110
|
+
"$ref": "#/components/schemas/RelationType"
|
|
8111
|
+
},
|
|
8112
|
+
"custom_label": {
|
|
8113
|
+
"type": [
|
|
8114
|
+
"string",
|
|
8115
|
+
"null"
|
|
8116
|
+
]
|
|
8117
|
+
},
|
|
8118
|
+
"since": {
|
|
8119
|
+
"type": [
|
|
8120
|
+
"integer",
|
|
8121
|
+
"null"
|
|
8122
|
+
],
|
|
8123
|
+
"description": "Unix timestamp in milliseconds."
|
|
8124
|
+
},
|
|
8125
|
+
"note": {
|
|
8126
|
+
"type": [
|
|
8127
|
+
"string",
|
|
8128
|
+
"null"
|
|
8129
|
+
]
|
|
8130
|
+
},
|
|
8131
|
+
"counterpart_name": {
|
|
8132
|
+
"type": "string"
|
|
8133
|
+
}
|
|
8134
|
+
}
|
|
8135
|
+
},
|
|
7373
8136
|
"PortalExport": {
|
|
7374
8137
|
"description": "Everything the workspace holds about the signed-in contact (GDPR Art. 15).",
|
|
7375
8138
|
"type": "object",
|
|
@@ -7378,7 +8141,8 @@
|
|
|
7378
8141
|
"contact",
|
|
7379
8142
|
"family",
|
|
7380
8143
|
"consents",
|
|
7381
|
-
"bookings"
|
|
8144
|
+
"bookings",
|
|
8145
|
+
"relations"
|
|
7382
8146
|
],
|
|
7383
8147
|
"properties": {
|
|
7384
8148
|
"exported_at": {
|
|
@@ -7405,6 +8169,12 @@
|
|
|
7405
8169
|
"items": {
|
|
7406
8170
|
"$ref": "#/components/schemas/PortalBooking"
|
|
7407
8171
|
}
|
|
8172
|
+
},
|
|
8173
|
+
"relations": {
|
|
8174
|
+
"type": "array",
|
|
8175
|
+
"items": {
|
|
8176
|
+
"$ref": "#/components/schemas/PortalExportRelation"
|
|
8177
|
+
}
|
|
7408
8178
|
}
|
|
7409
8179
|
}
|
|
7410
8180
|
},
|
|
@@ -8123,6 +8893,495 @@
|
|
|
8123
8893
|
"$ref": "#/components/schemas/ChannelConnectionDisconnectResult"
|
|
8124
8894
|
}
|
|
8125
8895
|
}
|
|
8896
|
+
},
|
|
8897
|
+
"RelationType": {
|
|
8898
|
+
"description": "How a person or a relation relates to a contact.",
|
|
8899
|
+
"type": "string",
|
|
8900
|
+
"enum": [
|
|
8901
|
+
"guardian",
|
|
8902
|
+
"owner",
|
|
8903
|
+
"employer",
|
|
8904
|
+
"caregiver",
|
|
8905
|
+
"partner",
|
|
8906
|
+
"custom"
|
|
8907
|
+
]
|
|
8908
|
+
},
|
|
8909
|
+
"ContactPerson": {
|
|
8910
|
+
"description": "A person a contact books for — a child, a pet, an employee. No login of their own.",
|
|
8911
|
+
"type": "object",
|
|
8912
|
+
"required": [
|
|
8913
|
+
"person_id",
|
|
8914
|
+
"contact_id",
|
|
8915
|
+
"name",
|
|
8916
|
+
"birth_year",
|
|
8917
|
+
"relation_type",
|
|
8918
|
+
"relation_label",
|
|
8919
|
+
"notes",
|
|
8920
|
+
"active",
|
|
8921
|
+
"promoted_to_contact_id",
|
|
8922
|
+
"created_at",
|
|
8923
|
+
"updated_at"
|
|
8924
|
+
],
|
|
8925
|
+
"properties": {
|
|
8926
|
+
"person_id": {
|
|
8927
|
+
"type": "string"
|
|
8928
|
+
},
|
|
8929
|
+
"contact_id": {
|
|
8930
|
+
"type": "string"
|
|
8931
|
+
},
|
|
8932
|
+
"name": {
|
|
8933
|
+
"type": "string"
|
|
8934
|
+
},
|
|
8935
|
+
"birth_year": {
|
|
8936
|
+
"type": [
|
|
8937
|
+
"integer",
|
|
8938
|
+
"null"
|
|
8939
|
+
]
|
|
8940
|
+
},
|
|
8941
|
+
"relation_type": {
|
|
8942
|
+
"$ref": "#/components/schemas/RelationType"
|
|
8943
|
+
},
|
|
8944
|
+
"relation_label": {
|
|
8945
|
+
"type": [
|
|
8946
|
+
"string",
|
|
8947
|
+
"null"
|
|
8948
|
+
]
|
|
8949
|
+
},
|
|
8950
|
+
"notes": {
|
|
8951
|
+
"type": [
|
|
8952
|
+
"string",
|
|
8953
|
+
"null"
|
|
8954
|
+
]
|
|
8955
|
+
},
|
|
8956
|
+
"active": {
|
|
8957
|
+
"type": "boolean"
|
|
8958
|
+
},
|
|
8959
|
+
"promoted_to_contact_id": {
|
|
8960
|
+
"type": [
|
|
8961
|
+
"string",
|
|
8962
|
+
"null"
|
|
8963
|
+
]
|
|
8964
|
+
},
|
|
8965
|
+
"created_at": {
|
|
8966
|
+
"type": "string",
|
|
8967
|
+
"format": "date-time"
|
|
8968
|
+
},
|
|
8969
|
+
"updated_at": {
|
|
8970
|
+
"type": "string",
|
|
8971
|
+
"format": "date-time"
|
|
8972
|
+
}
|
|
8973
|
+
}
|
|
8974
|
+
},
|
|
8975
|
+
"CreateContactPersonInput": {
|
|
8976
|
+
"type": "object",
|
|
8977
|
+
"required": [
|
|
8978
|
+
"contact_id",
|
|
8979
|
+
"name",
|
|
8980
|
+
"relation_type"
|
|
8981
|
+
],
|
|
8982
|
+
"properties": {
|
|
8983
|
+
"contact_id": {
|
|
8984
|
+
"type": "string"
|
|
8985
|
+
},
|
|
8986
|
+
"name": {
|
|
8987
|
+
"type": "string"
|
|
8988
|
+
},
|
|
8989
|
+
"birth_year": {
|
|
8990
|
+
"type": "integer"
|
|
8991
|
+
},
|
|
8992
|
+
"relation_type": {
|
|
8993
|
+
"$ref": "#/components/schemas/RelationType"
|
|
8994
|
+
},
|
|
8995
|
+
"relation_label": {
|
|
8996
|
+
"type": "string"
|
|
8997
|
+
},
|
|
8998
|
+
"notes": {
|
|
8999
|
+
"type": "string"
|
|
9000
|
+
}
|
|
9001
|
+
}
|
|
9002
|
+
},
|
|
9003
|
+
"ContactRelation": {
|
|
9004
|
+
"description": "One directional relation between two contacts.",
|
|
9005
|
+
"type": "object",
|
|
9006
|
+
"required": [
|
|
9007
|
+
"relation_id",
|
|
9008
|
+
"from_contact_id",
|
|
9009
|
+
"to_contact_id",
|
|
9010
|
+
"type",
|
|
9011
|
+
"custom_label",
|
|
9012
|
+
"since",
|
|
9013
|
+
"note",
|
|
9014
|
+
"counterpart_name",
|
|
9015
|
+
"created_at"
|
|
9016
|
+
],
|
|
9017
|
+
"properties": {
|
|
9018
|
+
"relation_id": {
|
|
9019
|
+
"type": "string"
|
|
9020
|
+
},
|
|
9021
|
+
"from_contact_id": {
|
|
9022
|
+
"type": "string"
|
|
9023
|
+
},
|
|
9024
|
+
"to_contact_id": {
|
|
9025
|
+
"type": "string"
|
|
9026
|
+
},
|
|
9027
|
+
"type": {
|
|
9028
|
+
"$ref": "#/components/schemas/RelationType"
|
|
9029
|
+
},
|
|
9030
|
+
"custom_label": {
|
|
9031
|
+
"type": [
|
|
9032
|
+
"string",
|
|
9033
|
+
"null"
|
|
9034
|
+
]
|
|
9035
|
+
},
|
|
9036
|
+
"since": {
|
|
9037
|
+
"type": [
|
|
9038
|
+
"integer",
|
|
9039
|
+
"null"
|
|
9040
|
+
],
|
|
9041
|
+
"description": "Unix timestamp in milliseconds."
|
|
9042
|
+
},
|
|
9043
|
+
"note": {
|
|
9044
|
+
"type": [
|
|
9045
|
+
"string",
|
|
9046
|
+
"null"
|
|
9047
|
+
]
|
|
9048
|
+
},
|
|
9049
|
+
"counterpart_name": {
|
|
9050
|
+
"type": "string",
|
|
9051
|
+
"description": "Empty string when the counterpart contact no longer exists."
|
|
9052
|
+
},
|
|
9053
|
+
"created_at": {
|
|
9054
|
+
"type": "string",
|
|
9055
|
+
"format": "date-time"
|
|
9056
|
+
}
|
|
9057
|
+
}
|
|
9058
|
+
},
|
|
9059
|
+
"ContactRelations": {
|
|
9060
|
+
"description": "Relations a contact holds, split by direction.",
|
|
9061
|
+
"type": "object",
|
|
9062
|
+
"required": [
|
|
9063
|
+
"outgoing",
|
|
9064
|
+
"incoming"
|
|
9065
|
+
],
|
|
9066
|
+
"properties": {
|
|
9067
|
+
"outgoing": {
|
|
9068
|
+
"type": "array",
|
|
9069
|
+
"items": {
|
|
9070
|
+
"$ref": "#/components/schemas/ContactRelation"
|
|
9071
|
+
}
|
|
9072
|
+
},
|
|
9073
|
+
"incoming": {
|
|
9074
|
+
"type": "array",
|
|
9075
|
+
"items": {
|
|
9076
|
+
"$ref": "#/components/schemas/ContactRelation"
|
|
9077
|
+
}
|
|
9078
|
+
}
|
|
9079
|
+
}
|
|
9080
|
+
},
|
|
9081
|
+
"CreateContactRelationInput": {
|
|
9082
|
+
"type": "object",
|
|
9083
|
+
"required": [
|
|
9084
|
+
"from_contact_id",
|
|
9085
|
+
"to_contact_id",
|
|
9086
|
+
"type"
|
|
9087
|
+
],
|
|
9088
|
+
"properties": {
|
|
9089
|
+
"from_contact_id": {
|
|
9090
|
+
"type": "string"
|
|
9091
|
+
},
|
|
9092
|
+
"to_contact_id": {
|
|
9093
|
+
"type": "string"
|
|
9094
|
+
},
|
|
9095
|
+
"type": {
|
|
9096
|
+
"$ref": "#/components/schemas/RelationType"
|
|
9097
|
+
},
|
|
9098
|
+
"custom_label": {
|
|
9099
|
+
"type": "string"
|
|
9100
|
+
},
|
|
9101
|
+
"since": {
|
|
9102
|
+
"type": "integer",
|
|
9103
|
+
"description": "Unix timestamp in milliseconds."
|
|
9104
|
+
},
|
|
9105
|
+
"note": {
|
|
9106
|
+
"type": "string"
|
|
9107
|
+
}
|
|
9108
|
+
}
|
|
9109
|
+
},
|
|
9110
|
+
"CreateContactRelationResult": {
|
|
9111
|
+
"type": "object",
|
|
9112
|
+
"required": [
|
|
9113
|
+
"relation_id"
|
|
9114
|
+
],
|
|
9115
|
+
"properties": {
|
|
9116
|
+
"relation_id": {
|
|
9117
|
+
"type": "string"
|
|
9118
|
+
}
|
|
9119
|
+
}
|
|
9120
|
+
},
|
|
9121
|
+
"BookingEventStatus": {
|
|
9122
|
+
"type": "string",
|
|
9123
|
+
"enum": [
|
|
9124
|
+
"draft",
|
|
9125
|
+
"open",
|
|
9126
|
+
"closed",
|
|
9127
|
+
"completed",
|
|
9128
|
+
"cancelled"
|
|
9129
|
+
]
|
|
9130
|
+
},
|
|
9131
|
+
"BookingEventTemplateKey": {
|
|
9132
|
+
"type": "string",
|
|
9133
|
+
"enum": [
|
|
9134
|
+
"kindergarten_visit",
|
|
9135
|
+
"company_day",
|
|
9136
|
+
"class",
|
|
9137
|
+
"open_day",
|
|
9138
|
+
"custom"
|
|
9139
|
+
]
|
|
9140
|
+
},
|
|
9141
|
+
"BookingEvent": {
|
|
9142
|
+
"description": "An arrangement — a scheduled group session bookings register against.",
|
|
9143
|
+
"type": "object",
|
|
9144
|
+
"required": [
|
|
9145
|
+
"event_id",
|
|
9146
|
+
"template_id",
|
|
9147
|
+
"host_id",
|
|
9148
|
+
"date",
|
|
9149
|
+
"window_start_minute",
|
|
9150
|
+
"window_end_minute",
|
|
9151
|
+
"place",
|
|
9152
|
+
"capacity",
|
|
9153
|
+
"minimum",
|
|
9154
|
+
"registered_count",
|
|
9155
|
+
"service_ids",
|
|
9156
|
+
"resource_ids",
|
|
9157
|
+
"price_override_ore",
|
|
9158
|
+
"status",
|
|
9159
|
+
"registration_closes_at",
|
|
9160
|
+
"slug",
|
|
9161
|
+
"created_at",
|
|
9162
|
+
"updated_at"
|
|
9163
|
+
],
|
|
9164
|
+
"properties": {
|
|
9165
|
+
"event_id": {
|
|
9166
|
+
"type": "string"
|
|
9167
|
+
},
|
|
9168
|
+
"template_id": {
|
|
9169
|
+
"type": "string"
|
|
9170
|
+
},
|
|
9171
|
+
"host_id": {
|
|
9172
|
+
"type": [
|
|
9173
|
+
"string",
|
|
9174
|
+
"null"
|
|
9175
|
+
]
|
|
9176
|
+
},
|
|
9177
|
+
"date": {
|
|
9178
|
+
"description": "yyyy-mm-dd in the workspace time zone.",
|
|
9179
|
+
"type": "string",
|
|
9180
|
+
"format": "date"
|
|
9181
|
+
},
|
|
9182
|
+
"window_start_minute": {
|
|
9183
|
+
"type": "integer"
|
|
9184
|
+
},
|
|
9185
|
+
"window_end_minute": {
|
|
9186
|
+
"type": "integer"
|
|
9187
|
+
},
|
|
9188
|
+
"place": {
|
|
9189
|
+
"type": "string",
|
|
9190
|
+
"enum": [
|
|
9191
|
+
"at_host",
|
|
9192
|
+
"in_house"
|
|
9193
|
+
]
|
|
9194
|
+
},
|
|
9195
|
+
"capacity": {
|
|
9196
|
+
"type": "integer"
|
|
9197
|
+
},
|
|
9198
|
+
"minimum": {
|
|
9199
|
+
"type": "integer"
|
|
9200
|
+
},
|
|
9201
|
+
"registered_count": {
|
|
9202
|
+
"type": "integer"
|
|
9203
|
+
},
|
|
9204
|
+
"service_ids": {
|
|
9205
|
+
"type": "array",
|
|
9206
|
+
"items": {
|
|
9207
|
+
"type": "string"
|
|
9208
|
+
}
|
|
9209
|
+
},
|
|
9210
|
+
"resource_ids": {
|
|
9211
|
+
"type": "array",
|
|
9212
|
+
"items": {
|
|
9213
|
+
"type": "string"
|
|
9214
|
+
}
|
|
9215
|
+
},
|
|
9216
|
+
"price_override_ore": {
|
|
9217
|
+
"type": [
|
|
9218
|
+
"integer",
|
|
9219
|
+
"null"
|
|
9220
|
+
]
|
|
9221
|
+
},
|
|
9222
|
+
"status": {
|
|
9223
|
+
"$ref": "#/components/schemas/BookingEventStatus"
|
|
9224
|
+
},
|
|
9225
|
+
"registration_closes_at": {
|
|
9226
|
+
"type": "string",
|
|
9227
|
+
"format": "date-time"
|
|
9228
|
+
},
|
|
9229
|
+
"slug": {
|
|
9230
|
+
"type": "string"
|
|
9231
|
+
},
|
|
9232
|
+
"created_at": {
|
|
9233
|
+
"type": "string",
|
|
9234
|
+
"format": "date-time"
|
|
9235
|
+
},
|
|
9236
|
+
"updated_at": {
|
|
9237
|
+
"type": "string",
|
|
9238
|
+
"format": "date-time"
|
|
9239
|
+
}
|
|
9240
|
+
}
|
|
9241
|
+
},
|
|
9242
|
+
"CreateBookingEventInput": {
|
|
9243
|
+
"type": "object",
|
|
9244
|
+
"required": [
|
|
9245
|
+
"template_key",
|
|
9246
|
+
"date",
|
|
9247
|
+
"window_start_minute",
|
|
9248
|
+
"place",
|
|
9249
|
+
"service_ids",
|
|
9250
|
+
"resource_ids"
|
|
9251
|
+
],
|
|
9252
|
+
"properties": {
|
|
9253
|
+
"template_key": {
|
|
9254
|
+
"$ref": "#/components/schemas/BookingEventTemplateKey"
|
|
9255
|
+
},
|
|
9256
|
+
"host_id": {
|
|
9257
|
+
"type": "string"
|
|
9258
|
+
},
|
|
9259
|
+
"date": {
|
|
9260
|
+
"type": "string",
|
|
9261
|
+
"format": "date"
|
|
9262
|
+
},
|
|
9263
|
+
"window_start_minute": {
|
|
9264
|
+
"type": "integer"
|
|
9265
|
+
},
|
|
9266
|
+
"window_end_minute": {
|
|
9267
|
+
"type": "integer"
|
|
9268
|
+
},
|
|
9269
|
+
"place": {
|
|
9270
|
+
"type": "string",
|
|
9271
|
+
"enum": [
|
|
9272
|
+
"at_host",
|
|
9273
|
+
"in_house"
|
|
9274
|
+
]
|
|
9275
|
+
},
|
|
9276
|
+
"capacity": {
|
|
9277
|
+
"type": "integer"
|
|
9278
|
+
},
|
|
9279
|
+
"minimum": {
|
|
9280
|
+
"type": "integer"
|
|
9281
|
+
},
|
|
9282
|
+
"service_ids": {
|
|
9283
|
+
"type": "array",
|
|
9284
|
+
"items": {
|
|
9285
|
+
"type": "string"
|
|
9286
|
+
}
|
|
9287
|
+
},
|
|
9288
|
+
"resource_ids": {
|
|
9289
|
+
"type": "array",
|
|
9290
|
+
"items": {
|
|
9291
|
+
"type": "string"
|
|
9292
|
+
}
|
|
9293
|
+
}
|
|
9294
|
+
}
|
|
9295
|
+
},
|
|
9296
|
+
"ApiResponse_ContactPersonArray": {
|
|
9297
|
+
"$ref": "#/components/schemas/Envelope_ContactPersonArray"
|
|
9298
|
+
},
|
|
9299
|
+
"ApiResponse_ContactPerson": {
|
|
9300
|
+
"$ref": "#/components/schemas/Envelope_ContactPerson"
|
|
9301
|
+
},
|
|
9302
|
+
"ApiResponse_ContactRelations": {
|
|
9303
|
+
"$ref": "#/components/schemas/Envelope_ContactRelations"
|
|
9304
|
+
},
|
|
9305
|
+
"ApiResponse_CreateContactRelationResult": {
|
|
9306
|
+
"$ref": "#/components/schemas/Envelope_CreateContactRelationResult"
|
|
9307
|
+
},
|
|
9308
|
+
"ApiResponse_BookingEventArray": {
|
|
9309
|
+
"$ref": "#/components/schemas/Envelope_BookingEventArray"
|
|
9310
|
+
},
|
|
9311
|
+
"ApiResponse_BookingEvent": {
|
|
9312
|
+
"$ref": "#/components/schemas/Envelope_BookingEvent"
|
|
9313
|
+
},
|
|
9314
|
+
"Envelope_ContactPersonArray": {
|
|
9315
|
+
"type": "object",
|
|
9316
|
+
"required": [
|
|
9317
|
+
"data"
|
|
9318
|
+
],
|
|
9319
|
+
"properties": {
|
|
9320
|
+
"data": {
|
|
9321
|
+
"type": "array",
|
|
9322
|
+
"items": {
|
|
9323
|
+
"$ref": "#/components/schemas/ContactPerson"
|
|
9324
|
+
}
|
|
9325
|
+
}
|
|
9326
|
+
}
|
|
9327
|
+
},
|
|
9328
|
+
"Envelope_ContactPerson": {
|
|
9329
|
+
"type": "object",
|
|
9330
|
+
"required": [
|
|
9331
|
+
"data"
|
|
9332
|
+
],
|
|
9333
|
+
"properties": {
|
|
9334
|
+
"data": {
|
|
9335
|
+
"$ref": "#/components/schemas/ContactPerson"
|
|
9336
|
+
}
|
|
9337
|
+
}
|
|
9338
|
+
},
|
|
9339
|
+
"Envelope_ContactRelations": {
|
|
9340
|
+
"type": "object",
|
|
9341
|
+
"required": [
|
|
9342
|
+
"data"
|
|
9343
|
+
],
|
|
9344
|
+
"properties": {
|
|
9345
|
+
"data": {
|
|
9346
|
+
"$ref": "#/components/schemas/ContactRelations"
|
|
9347
|
+
}
|
|
9348
|
+
}
|
|
9349
|
+
},
|
|
9350
|
+
"Envelope_CreateContactRelationResult": {
|
|
9351
|
+
"type": "object",
|
|
9352
|
+
"required": [
|
|
9353
|
+
"data"
|
|
9354
|
+
],
|
|
9355
|
+
"properties": {
|
|
9356
|
+
"data": {
|
|
9357
|
+
"$ref": "#/components/schemas/CreateContactRelationResult"
|
|
9358
|
+
}
|
|
9359
|
+
}
|
|
9360
|
+
},
|
|
9361
|
+
"Envelope_BookingEventArray": {
|
|
9362
|
+
"type": "object",
|
|
9363
|
+
"required": [
|
|
9364
|
+
"data"
|
|
9365
|
+
],
|
|
9366
|
+
"properties": {
|
|
9367
|
+
"data": {
|
|
9368
|
+
"type": "array",
|
|
9369
|
+
"items": {
|
|
9370
|
+
"$ref": "#/components/schemas/BookingEvent"
|
|
9371
|
+
}
|
|
9372
|
+
}
|
|
9373
|
+
}
|
|
9374
|
+
},
|
|
9375
|
+
"Envelope_BookingEvent": {
|
|
9376
|
+
"type": "object",
|
|
9377
|
+
"required": [
|
|
9378
|
+
"data"
|
|
9379
|
+
],
|
|
9380
|
+
"properties": {
|
|
9381
|
+
"data": {
|
|
9382
|
+
"$ref": "#/components/schemas/BookingEvent"
|
|
9383
|
+
}
|
|
9384
|
+
}
|
|
8126
9385
|
}
|
|
8127
9386
|
}
|
|
8128
9387
|
}
|