@epilot/cli 0.1.68 → 0.1.70

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.
@@ -243,6 +243,42 @@
243
243
  }
244
244
  }
245
245
  },
246
+ "/v1/campaign:discover": {
247
+ "post": {
248
+ "operationId": "discoverCampaigns",
249
+ "summary": "Discover Entity-UI Next Best Actions for an entity",
250
+ "description": "Given an entity, returns the Next Best Actions it should see on the Entity-UI channel.\n\nEnumerates the organization's **active** campaigns that carry a valid Entity-UI Next Best\nAction, live-matches each against the entity using the existing match engine, and returns\nthe matching NBAs priority-sorted (one per campaign).\n\nThis is a pure read: it writes nothing. An entity that matches no campaigns returns an\nempty list, not an error.\n",
251
+ "tags": [
252
+ "Campaign"
253
+ ],
254
+ "security": [
255
+ {
256
+ "EpilotAuth": []
257
+ }
258
+ ],
259
+ "requestBody": {
260
+ "required": true,
261
+ "content": {
262
+ "application/json": {
263
+ "schema": {
264
+ "$ref": "#/components/schemas/DiscoverCampaignsParams"
265
+ }
266
+ }
267
+ }
268
+ },
269
+ "responses": {
270
+ "200": {
271
+ "$ref": "#/components/responses/DiscoverCampaignsResponse"
272
+ },
273
+ "400": {
274
+ "$ref": "#/components/responses/ClientErrorResponse"
275
+ },
276
+ "500": {
277
+ "$ref": "#/components/responses/ServerErrorResponse"
278
+ }
279
+ }
280
+ }
281
+ },
246
282
  "/v1/target:match": {
247
283
  "post": {
248
284
  "operationId": "matchTargets",
@@ -450,6 +486,56 @@
450
486
  }
451
487
  }
452
488
  },
489
+ "/v1/campaign/{campaign_id}/recipient/{recipient_id}/entity_ui:status": {
490
+ "patch": {
491
+ "operationId": "updateRecipientEntityUiStatus",
492
+ "summary": "Update Entity-UI (Next Best Action) status for a campaign recipient",
493
+ "description": "Records a Next Best Action interaction for a recipient on the Entity-UI channel.\n\nUnlike the portal channel, an NBA recipient is created lazily: the first `seen` creates\nthe recipient record (and requires `entity_schema`). `seen` is idempotent — re-viewing an\nNBA that is already seen/clicked/dismissed is a no-op success and never regresses the status.\n\nStatus transition rules:\n- `seen`: lazily creates the recipient; a no-op success if a status already exists\n- From `seen`: can change to `clicked` or `dismissed`\n- From `clicked`: can change to `dismissed`\n- From `dismissed`: cannot be changed (final state)\n\n`dismissed` and `clicked` require an existing recipient (404 otherwise, since an NBA is\nborn at `seen`) and reject invalid transitions (409).\n\nThe entity_ui_status_updated_at timestamp is automatically set when the status changes.\n",
494
+ "tags": [
495
+ "Campaign Recipient"
496
+ ],
497
+ "security": [
498
+ {
499
+ "EpilotAuth": []
500
+ }
501
+ ],
502
+ "parameters": [
503
+ {
504
+ "$ref": "#/components/parameters/CampaignIdPathParam"
505
+ },
506
+ {
507
+ "$ref": "#/components/parameters/RecipientIdPathParam"
508
+ }
509
+ ],
510
+ "requestBody": {
511
+ "required": true,
512
+ "content": {
513
+ "application/json": {
514
+ "schema": {
515
+ "$ref": "#/components/schemas/UpdateEntityUiStatusRequest"
516
+ }
517
+ }
518
+ }
519
+ },
520
+ "responses": {
521
+ "200": {
522
+ "$ref": "#/components/responses/RecipientResponse"
523
+ },
524
+ "400": {
525
+ "$ref": "#/components/responses/ClientErrorResponse"
526
+ },
527
+ "404": {
528
+ "$ref": "#/components/responses/ClientErrorResponse"
529
+ },
530
+ "409": {
531
+ "$ref": "#/components/responses/ClientErrorResponse"
532
+ },
533
+ "500": {
534
+ "$ref": "#/components/responses/ServerErrorResponse"
535
+ }
536
+ }
537
+ }
538
+ },
453
539
  "/v1/campaign/{campaign_id}/recipients": {
454
540
  "get": {
455
541
  "operationId": "getRecipients",
@@ -918,6 +1004,122 @@
918
1004
  ],
919
1005
  "additionalProperties": false
920
1006
  },
1007
+ "NextBestAction": {
1008
+ "type": "object",
1009
+ "description": "A Next Best Action configured on a campaign's Entity-UI channel.\nThis is the canonical NBA contract shared by discovery (this API), authoring, and rendering.\nNBA content is single-language in v1; text fields may contain `{{placeholders}}` resolved at render time.\n",
1010
+ "properties": {
1011
+ "category": {
1012
+ "type": "string",
1013
+ "description": "Light category label shown above the title. Free-form text."
1014
+ },
1015
+ "icon": {
1016
+ "type": "object",
1017
+ "description": "Curated icon for the NBA.",
1018
+ "properties": {
1019
+ "name": {
1020
+ "type": "string",
1021
+ "description": "Icon name from \"@epilot360/icons\"."
1022
+ },
1023
+ "color": {
1024
+ "type": "string",
1025
+ "description": "Optional icon color."
1026
+ }
1027
+ },
1028
+ "required": [
1029
+ "name"
1030
+ ]
1031
+ },
1032
+ "title": {
1033
+ "type": "string",
1034
+ "description": "Bold action title. Required. Supports `{{placeholders}}`."
1035
+ },
1036
+ "body": {
1037
+ "type": "string",
1038
+ "description": "Optional description. Supports `{{placeholders}}` (incl. relative dates)."
1039
+ },
1040
+ "priority": {
1041
+ "type": "string",
1042
+ "enum": [
1043
+ "low",
1044
+ "medium",
1045
+ "high"
1046
+ ],
1047
+ "default": "medium",
1048
+ "description": "Display priority. NBAs are shown highest-priority first."
1049
+ },
1050
+ "is_dismissable": {
1051
+ "type": "boolean",
1052
+ "default": true,
1053
+ "description": "Whether the agent can dismiss the NBA."
1054
+ },
1055
+ "cta": {
1056
+ "type": "object",
1057
+ "description": "The NBA's single call-to-action.",
1058
+ "properties": {
1059
+ "type": {
1060
+ "type": "string",
1061
+ "enum": [
1062
+ "journey",
1063
+ "workflow",
1064
+ "url"
1065
+ ]
1066
+ },
1067
+ "target": {
1068
+ "type": "string",
1069
+ "description": "Journey id, workflow definition id, or URL, depending on `type`."
1070
+ },
1071
+ "label": {
1072
+ "type": "string",
1073
+ "description": "Optional CTA button label."
1074
+ },
1075
+ "context_params": {
1076
+ "type": "array",
1077
+ "description": "Journey context parameters (journey CTA only). Maps the journey's declared\ncontext parameters so the journey knows which entity it is about. Discovery\nreturns them verbatim; they are passed to the journey when it launches.\n",
1078
+ "items": {
1079
+ "type": "object",
1080
+ "properties": {
1081
+ "key": {
1082
+ "type": "string"
1083
+ },
1084
+ "value": {
1085
+ "type": "string"
1086
+ }
1087
+ },
1088
+ "required": [
1089
+ "key",
1090
+ "value"
1091
+ ]
1092
+ }
1093
+ }
1094
+ },
1095
+ "required": [
1096
+ "type",
1097
+ "target"
1098
+ ]
1099
+ }
1100
+ },
1101
+ "required": [
1102
+ "title",
1103
+ "cta"
1104
+ ]
1105
+ },
1106
+ "DiscoverCampaignsParams": {
1107
+ "type": "object",
1108
+ "properties": {
1109
+ "entity_id": {
1110
+ "$ref": "#/components/schemas/BaseUUID"
1111
+ },
1112
+ "entity_schema": {
1113
+ "type": "string",
1114
+ "description": "The schema slug of the entity (e.g. \"contact\" or \"account\")."
1115
+ }
1116
+ },
1117
+ "required": [
1118
+ "entity_id",
1119
+ "entity_schema"
1120
+ ],
1121
+ "additionalProperties": false
1122
+ },
921
1123
  "MatchTargetParams": {
922
1124
  "type": "object",
923
1125
  "properties": {
@@ -1022,6 +1224,22 @@
1022
1224
  "clicked"
1023
1225
  ]
1024
1226
  },
1227
+ "EntityUiStatus": {
1228
+ "type": "string",
1229
+ "description": "Lifecycle status of a Next Best Action on the Entity-UI channel. Unlike the portal\nchannel there is no `sent` state: an NBA recipient is born at `seen`, the moment the\naction is first rendered to an agent.\n",
1230
+ "enum": [
1231
+ "seen",
1232
+ "dismissed",
1233
+ "clicked"
1234
+ ]
1235
+ },
1236
+ "Resolution": {
1237
+ "type": "string",
1238
+ "description": "Cross-channel resolution of a campaign for a recipient. Unlike the per-channel `*_status`\nfields (where `dismissed` is channel-local), a resolution suppresses the campaign on EVERY\nchannel — the 360 Entity-UI card and the portal teaser alike. Server-managed and read-only:\nnever sent by a client. Absence means unresolved.\n",
1239
+ "enum": [
1240
+ "accepted"
1241
+ ]
1242
+ },
1025
1243
  "Recipient": {
1026
1244
  "type": "object",
1027
1245
  "properties": {
@@ -1051,6 +1269,16 @@
1051
1269
  "type": "object",
1052
1270
  "additionalProperties": true
1053
1271
  },
1272
+ "entity_ui_status": {
1273
+ "$ref": "#/components/schemas/EntityUiStatus"
1274
+ },
1275
+ "entity_ui_status_updated_at": {
1276
+ "type": "string",
1277
+ "format": "date-time"
1278
+ },
1279
+ "resolution": {
1280
+ "$ref": "#/components/schemas/Resolution"
1281
+ },
1054
1282
  "updated_at": {
1055
1283
  "type": "string",
1056
1284
  "format": "date-time"
@@ -1216,6 +1444,22 @@
1216
1444
  "status"
1217
1445
  ]
1218
1446
  },
1447
+ "UpdateEntityUiStatusRequest": {
1448
+ "type": "object",
1449
+ "properties": {
1450
+ "status": {
1451
+ "$ref": "#/components/schemas/EntityUiStatus"
1452
+ },
1453
+ "entity_schema": {
1454
+ "type": "string",
1455
+ "description": "Schema slug of the recipient entity (e.g. \"contact\"). Required when recording the\nfirst `seen`, which lazily creates the recipient record; ignored on later transitions.\n"
1456
+ }
1457
+ },
1458
+ "required": [
1459
+ "status"
1460
+ ],
1461
+ "additionalProperties": false
1462
+ },
1219
1463
  "SetupCampaignRequest": {
1220
1464
  "description": "Discriminated by `type`. Each campaign variant has its own request shape;\nnew variants are added by introducing a new schema and extending the `oneOf` list.\n",
1221
1465
  "oneOf": [
@@ -1561,6 +1805,53 @@
1561
1805
  }
1562
1806
  }
1563
1807
  },
1808
+ "DiscoverCampaignsResponse": {
1809
+ "description": "The Next Best Actions the entity should see on the Entity-UI channel, priority-sorted.",
1810
+ "content": {
1811
+ "application/json": {
1812
+ "schema": {
1813
+ "type": "object",
1814
+ "properties": {
1815
+ "hits": {
1816
+ "type": "number",
1817
+ "description": "Number of matching NBAs."
1818
+ },
1819
+ "results": {
1820
+ "type": "array",
1821
+ "description": "Matching NBAs, sorted by priority (desc); one entry per campaign.",
1822
+ "items": {
1823
+ "type": "object",
1824
+ "properties": {
1825
+ "campaign_id": {
1826
+ "$ref": "#/components/schemas/BaseUUID"
1827
+ },
1828
+ "nba": {
1829
+ "$ref": "#/components/schemas/NextBestAction"
1830
+ },
1831
+ "status": {
1832
+ "allOf": [
1833
+ {
1834
+ "$ref": "#/components/schemas/EntityUiStatus"
1835
+ }
1836
+ ],
1837
+ "description": "The recipient's current Entity-UI status for this campaign, present only\nwhen a recipient record already exists (i.e. the entity has previously seen\nor clicked this NBA). Absent when the entity has not yet interacted with it.\nDismissed NBAs are filtered out server-side, so this is only ever `seen` or\n`clicked`. Lets the client skip a redundant `seen` call for NBAs already seen.\n"
1838
+ }
1839
+ },
1840
+ "required": [
1841
+ "campaign_id",
1842
+ "nba"
1843
+ ]
1844
+ }
1845
+ }
1846
+ },
1847
+ "required": [
1848
+ "hits",
1849
+ "results"
1850
+ ]
1851
+ }
1852
+ }
1853
+ }
1854
+ },
1564
1855
  "MatchTargetsResponse": {
1565
1856
  "description": "List of targets where the given entities are found.",
1566
1857
  "content": {
@@ -1046,6 +1046,117 @@
1046
1046
  }
1047
1047
  }
1048
1048
  },
1049
+ "/v2/users/public/resetPassword": {
1050
+ "post": {
1051
+ "operationId": "resetPassword",
1052
+ "summary": "resetPassword",
1053
+ "description": "Set a new password using a reset token from the password reset email.\nThe token is single-use and time-limited.\n",
1054
+ "security": [],
1055
+ "x-rate-limit": {
1056
+ "limit": 10
1057
+ },
1058
+ "tags": [
1059
+ "User V2"
1060
+ ],
1061
+ "requestBody": {
1062
+ "required": true,
1063
+ "content": {
1064
+ "application/json": {
1065
+ "schema": {
1066
+ "type": "object",
1067
+ "required": [
1068
+ "email",
1069
+ "token",
1070
+ "password"
1071
+ ],
1072
+ "properties": {
1073
+ "email": {
1074
+ "type": "string",
1075
+ "description": "Email address of the account",
1076
+ "example": "test@example.com"
1077
+ },
1078
+ "token": {
1079
+ "type": "string",
1080
+ "description": "Reset token from the password reset email"
1081
+ },
1082
+ "password": {
1083
+ "type": "string",
1084
+ "description": "The new password"
1085
+ }
1086
+ }
1087
+ }
1088
+ }
1089
+ }
1090
+ },
1091
+ "responses": {
1092
+ "200": {
1093
+ "description": "Password reset successfully",
1094
+ "content": {
1095
+ "application/json": {
1096
+ "schema": {
1097
+ "type": "object",
1098
+ "required": [
1099
+ "success"
1100
+ ],
1101
+ "properties": {
1102
+ "success": {
1103
+ "type": "boolean",
1104
+ "example": true
1105
+ }
1106
+ }
1107
+ }
1108
+ }
1109
+ }
1110
+ },
1111
+ "400": {
1112
+ "description": "Invalid or expired reset link, or password does not meet the requirements",
1113
+ "content": {
1114
+ "application/json": {
1115
+ "schema": {
1116
+ "type": "object",
1117
+ "required": [
1118
+ "error",
1119
+ "message"
1120
+ ],
1121
+ "properties": {
1122
+ "error": {
1123
+ "type": "string",
1124
+ "description": "Discriminator distinguishing token errors from policy errors",
1125
+ "enum": [
1126
+ "INVALID_RESET_LINK",
1127
+ "PASSWORD_POLICY"
1128
+ ]
1129
+ },
1130
+ "message": {
1131
+ "type": "string",
1132
+ "example": "Password does not meet the requirements"
1133
+ },
1134
+ "violations": {
1135
+ "type": "array",
1136
+ "description": "Itemized password-policy violation codes (only present when error is PASSWORD_POLICY)",
1137
+ "items": {
1138
+ "type": "string",
1139
+ "enum": [
1140
+ "too_short",
1141
+ "missing_lowercase",
1142
+ "missing_uppercase",
1143
+ "missing_number",
1144
+ "missing_symbol"
1145
+ ]
1146
+ },
1147
+ "example": [
1148
+ "too_short",
1149
+ "missing_uppercase"
1150
+ ]
1151
+ }
1152
+ }
1153
+ }
1154
+ }
1155
+ }
1156
+ }
1157
+ }
1158
+ }
1159
+ },
1049
1160
  "/v2/users/public/checkToken": {
1050
1161
  "get": {
1051
1162
  "operationId": "checkInviteToken",
@@ -1998,6 +2109,19 @@
1998
2109
  "format": "date-time",
1999
2110
  "readOnly": true
2000
2111
  },
2112
+ "password_reset_token_hash": {
2113
+ "description": "Internal: sha256 hash of the active password-reset token. Server-set, never returned in responses.",
2114
+ "type": "string",
2115
+ "nullable": true,
2116
+ "readOnly": true
2117
+ },
2118
+ "password_reset_token_expires_at": {
2119
+ "description": "Internal: expiry for the active password-reset token (ISO 8601). Server-set, never returned in responses.",
2120
+ "type": "string",
2121
+ "nullable": true,
2122
+ "format": "date-time",
2123
+ "readOnly": true
2124
+ },
2001
2125
  "department": {
2002
2126
  "type": "string",
2003
2127
  "description": "User's department",
@@ -2130,6 +2254,17 @@
2130
2254
  "deleted_opportunity": true
2131
2255
  }
2132
2256
  },
2257
+ "in_app_notification_setting": {
2258
+ "type": "object",
2259
+ "additionalProperties": true,
2260
+ "description": "Per-notification-type in-app delivery preferences (notification type key -> enabled). Written by the my-account notification settings UI and honored by svc-notification-api at delivery time. Absent or partial keys fall back to each notification type's configured default. Mirrors email_notification_setting for the in-app channel.",
2261
+ "example": {
2262
+ "integration_critical_error": true,
2263
+ "integration_error_threshold": true,
2264
+ "assigned_opportunity": true,
2265
+ "assigned_task": true
2266
+ }
2267
+ },
2133
2268
  "properties": {
2134
2269
  "type": "array",
2135
2270
  "items": {
@@ -2149,6 +2284,17 @@
2149
2284
  "value"
2150
2285
  ]
2151
2286
  }
2287
+ },
2288
+ "tags": {
2289
+ "type": "array",
2290
+ "description": "User tags/labels assigned for classification (e.g. label slugs)",
2291
+ "nullable": true,
2292
+ "items": {
2293
+ "type": "string"
2294
+ },
2295
+ "example": [
2296
+ "non-billable"
2297
+ ]
2152
2298
  }
2153
2299
  }
2154
2300
  },
@@ -1094,14 +1094,15 @@
1094
1094
  },
1095
1095
  "WebhookCondition": {
1096
1096
  "type": "object",
1097
- "description": "A condition that must be met for the webhook to fire.",
1097
+ "description": "A condition that must be met for the webhook to fire. A condition is EITHER a classic field + operation comparison OR a single jsonata_expression evaluated against the event payload — the two forms are mutually exclusive.",
1098
1098
  "properties": {
1099
1099
  "field": {
1100
1100
  "type": "string",
1101
- "description": "Dot-notation path to the field in the event payload (e.g. \"entity.status\", \"entity.line_items\")"
1101
+ "description": "Dot-notation path to the field in the event payload (e.g. \"entity.status\", \"entity.line_items\"). Supports array indices in either spelling, which resolve identically: \"meter_readings.1.file_id\" or \"meter_readings[1].file_id\"."
1102
1102
  },
1103
1103
  "operation": {
1104
1104
  "type": "string",
1105
+ "description": "Comparison operator. The length_* operations compare the item count of the field value (an array yields its length, a missing or null field yields 0, and any single non-array value yields 1) against values[0], which must be a non-negative integer.",
1105
1106
  "enum": [
1106
1107
  "equals",
1107
1108
  "not_equals",
@@ -1116,7 +1117,13 @@
1116
1117
  "greater_than_or_equals",
1117
1118
  "less_than_or_equals",
1118
1119
  "is_empty",
1119
- "is_not_empty"
1120
+ "is_not_empty",
1121
+ "length_equals",
1122
+ "length_not_equals",
1123
+ "length_greater_than",
1124
+ "length_less_than",
1125
+ "length_greater_than_or_equals",
1126
+ "length_less_than_or_equals"
1120
1127
  ]
1121
1128
  },
1122
1129
  "values": {
@@ -1147,12 +1154,13 @@
1147
1154
  "type": "boolean",
1148
1155
  "description": "When true, evaluates conditions per-item in repeatable array fields",
1149
1156
  "default": false
1157
+ },
1158
+ "jsonata_expression": {
1159
+ "type": "string",
1160
+ "maxLength": 15000,
1161
+ "description": "JSONata expression evaluated against the event payload; the condition passes when the result is truthy per JSONata $boolean semantics. Mutually exclusive with field/operation."
1150
1162
  }
1151
- },
1152
- "required": [
1153
- "field",
1154
- "operation"
1155
- ]
1163
+ }
1156
1164
  },
1157
1165
  "WebhookConditionGroup": {
1158
1166
  "type": "object",
@@ -1498,7 +1506,8 @@
1498
1506
  ],
1499
1507
  "properties": {
1500
1508
  "status_code": {
1501
- "type": "string"
1509
+ "type": "string",
1510
+ "description": "The HTTP status returned by the customer endpoint (or the upstream gateway). ABSENT for epilot-internal errors (code INTERNAL_ERROR / INTERNAL_RESPONSE_TOO_LARGE), which are not customer HTTP outcomes; PRESENT only for real HTTP/upstream results. When the response was delivered but too large to record, a recovered delivered status may still be present."
1502
1511
  },
1503
1512
  "message": {
1504
1513
  "type": "string"
@@ -1507,7 +1516,8 @@
1507
1516
  "type": "object"
1508
1517
  },
1509
1518
  "code": {
1510
- "type": "string"
1519
+ "type": "string",
1520
+ "description": "Machine-readable classification of the outcome. Known values: OAuthTokenExchangeError (OAuth token exchange / upstream gateway failure), DataLimitExceeded (legacy oversized-response marker), INTERNAL_RESPONSE_TOO_LARGE (request delivered but the response was too large for epilot to record), INTERNAL_ERROR (epilot-internal processing failure — not a customer HTTP outcome)."
1511
1521
  },
1512
1522
  "status": {
1513
1523
  "type": "string",
@@ -1678,7 +1688,8 @@
1678
1688
  "type": "object",
1679
1689
  "properties": {
1680
1690
  "status_code": {
1681
- "type": "integer"
1691
+ "type": "integer",
1692
+ "description": "The HTTP status returned by the customer endpoint (or the upstream gateway). ABSENT for epilot-internal errors (code INTERNAL_ERROR / INTERNAL_RESPONSE_TOO_LARGE), which are not customer HTTP outcomes; PRESENT only for real HTTP/upstream results. When the response was delivered but too large to record, a recovered delivered status may still be present."
1682
1693
  },
1683
1694
  "message": {
1684
1695
  "type": "string"
@@ -1687,7 +1698,8 @@
1687
1698
  "type": "object"
1688
1699
  },
1689
1700
  "code": {
1690
- "type": "string"
1701
+ "type": "string",
1702
+ "description": "Machine-readable classification of the outcome. Known values: OAuthTokenExchangeError (OAuth token exchange / upstream gateway failure), DataLimitExceeded (legacy oversized-response marker), INTERNAL_RESPONSE_TOO_LARGE (request delivered but the response was too large for epilot to record), INTERNAL_ERROR (epilot-internal processing failure — not a customer HTTP outcome)."
1691
1703
  }
1692
1704
  }
1693
1705
  },