Skip to content

Commit bf95a29

Browse files
author
bardonadam
committed
docs: publish tags in the public API specification
Why: - Expose optional history tags for push notifications and Live Activities. - Keep action and redirection URL schemes aligned with the supported API contract. How: - Add shared tag schemas, request and response fields, examples, and validation responses. - Document managed-stream tag preservation, replacement, and clearing. - Document HTTP, HTTPS, and Shortcuts URL support where applicable. Verification: - jq empty api-reference/openapi.json - npx --yes @redocly/cli lint api-reference/openapi.json --format=json - git diff --cached --check Spec: api-reference/openapi.json Initiated-by: shared Implemented-by: codex
1 parent 000131b commit bf95a29

1 file changed

Lines changed: 120 additions & 12 deletions

File tree

api-reference/openapi.json

Lines changed: 120 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@
175175
"post": {
176176
"tags": ["PushNotifications"],
177177
"summary": "Send a push notification",
178-
"description": "Sends a push notification to devices matched by API key scope and optional target channels. Supports optional redirection URL, optional media preview or playback when the notification is expanded, and up to 4 interactive actions. `media` cannot be combined with `actions`.",
178+
"description": "Sends a push notification to devices matched by API key scope and optional target channels. Supports optional redirection URL, optional media preview or playback when the notification is expanded, and up to 4 interactive actions. `media` cannot be combined with `actions`. Optional tags to organize and filter notification history.",
179179
"operationId": "sendPushNotification",
180180
"x-codeSamples": [
181181
{
@@ -288,6 +288,14 @@
288288
}
289289
]
290290
}
291+
},
292+
"tagged": {
293+
"summary": "Organize notification history with tags",
294+
"value": {
295+
"title": "New subscription 💸",
296+
"message": "Customer upgraded to Pro plan",
297+
"tags": ["user:382", "billing"]
298+
}
291299
}
292300
}
293301
}
@@ -316,6 +324,16 @@
316324
"effective_channel_slugs": ["devs", "ops"],
317325
"timestamp": "2025-08-12T12:00:00.000Z"
318326
}
327+
},
328+
"tagged": {
329+
"value": {
330+
"success": true,
331+
"devices_notified": 2,
332+
"users_notified": 1,
333+
"effective_channel_slugs": null,
334+
"tags": ["user:382", "billing"],
335+
"timestamp": "2025-08-12T12:00:00.000Z"
336+
}
319337
}
320338
}
321339
}
@@ -332,6 +350,13 @@
332350
"error": "Invalid channel targeting",
333351
"message": "target.channels must be an array of channel slugs"
334352
}
353+
},
354+
"invalid_tags": {
355+
"value": {
356+
"error": "Invalid tags",
357+
"code": "invalid_tags",
358+
"message": "tags must use 1-64 lowercase letters, numbers, dashes, underscores, periods, or colons"
359+
}
335360
}
336361
}
337362
}
@@ -398,7 +423,7 @@
398423
"put": {
399424
"tags": ["LiveActivities"],
400425
"summary": "Start a new Live Activity or update an existing one",
401-
"description": "Use a stable stream_key for each ongoing thing you want to show as a Live Activity. Send the latest content_state whenever it changes, and ActivitySmith will keep the Live Activity in sync. For timer streams, send duration_seconds to start or reset the timer; omit duration_seconds on later updates to preserve the existing timer window. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities.",
426+
"description": "Use a stable stream_key for each ongoing thing you want to show as a Live Activity. Send the latest content_state whenever it changes, and ActivitySmith will keep the Live Activity in sync. For timer streams, send duration_seconds to start or reset the timer; omit duration_seconds on later updates to preserve the existing timer window. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities. Optional tags to organize and filter notification history. On later stream updates, omit tags to keep the current tags, send tags again to replace them, or send an empty array to clear them.",
402427
"operationId": "reconcileLiveActivityStream",
403428
"x-activitysmith-lifecycle": "recommended_managed",
404429
"x-codeSamples": [
@@ -533,6 +558,18 @@
533558
}
534559
}
535560
}
561+
},
562+
"tagged": {
563+
"summary": "Organize notification history with tags",
564+
"value": {
565+
"content_state": {
566+
"title": "Search Reindex",
567+
"subtitle": "catalog-v2",
568+
"type": "progress",
569+
"percentage": 42
570+
},
571+
"tags": ["user:382", "search-reindex"]
572+
}
536573
}
537574
}
538575
}
@@ -572,6 +609,17 @@
572609
"activity_id": null,
573610
"timestamp": "2025-08-12T12:10:00.000Z"
574611
}
612+
},
613+
"tagged": {
614+
"value": {
615+
"success": true,
616+
"operation": "started",
617+
"stream_key": "search-reindex",
618+
"activity_id": "h8QmSyYFTuwOIF6Wh3YcZlzHLhUcr034",
619+
"devices_notified": 2,
620+
"tags": ["user:382", "search-reindex"],
621+
"timestamp": "2025-08-12T12:00:00.000Z"
622+
}
575623
}
576624
}
577625
}
@@ -594,6 +642,13 @@
594642
"error": "Invalid channel targeting",
595643
"message": "channels must contain at least one channel"
596644
}
645+
},
646+
"invalid_tags": {
647+
"value": {
648+
"error": "Invalid tags",
649+
"code": "invalid_tags",
650+
"message": "tags must contain at most 20 unique values"
651+
}
597652
}
598653
}
599654
}
@@ -833,7 +888,7 @@
833888
"post": {
834889
"tags": ["LiveActivities"],
835890
"summary": "Start a Live Activity (legacy manual lifecycle)",
836-
"description": "Legacy manual lifecycle endpoint. For new integrations, use PUT /live-activity/stream/{stream_key} so ActivitySmith can manage start, update, rotation, and end state for you. This endpoint remains supported for existing integrations and advanced lifecycle control. Starts a Live Activity on devices matched by API key scope and optional target channels. Supports segmented_progress, progress, metrics, stats, alert, and timer activity types. For segmented_progress activities, number_of_steps can be changed later during update or end calls if the workflow changes. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities.",
891+
"description": "Legacy manual lifecycle endpoint. For new integrations, use PUT /live-activity/stream/{stream_key} so ActivitySmith can manage start, update, rotation, and end state for you. This endpoint remains supported for existing integrations and advanced lifecycle control. Starts a Live Activity on devices matched by API key scope and optional target channels. Supports segmented_progress, progress, metrics, stats, alert, and timer activity types. For segmented_progress activities, number_of_steps can be changed later during update or end calls if the workflow changes. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities. Optional tags to organize and filter notification history.",
837892
"operationId": "startLiveActivity",
838893
"x-activitysmith-lifecycle": "legacy_manual",
839894
"x-activitysmith-recommended-alternative": "PUT /live-activity/stream/{stream_key}",
@@ -988,6 +1043,20 @@
9881043
}
9891044
}
9901045
}
1046+
},
1047+
"tagged": {
1048+
"summary": "Organize notification history with tags",
1049+
"value": {
1050+
"content_state": {
1051+
"title": "Nightly database backup",
1052+
"subtitle": "create snapshot",
1053+
"number_of_steps": 3,
1054+
"current_step": 1,
1055+
"type": "segmented_progress",
1056+
"color": "yellow"
1057+
},
1058+
"tags": ["user:382", "database-backup"]
1059+
}
9911060
}
9921061
}
9931062
}
@@ -1018,6 +1087,16 @@
10181087
"effective_channel_slugs": ["devs", "ops"],
10191088
"timestamp": "2026-01-28T09:57:22.929Z"
10201089
}
1090+
},
1091+
"tagged": {
1092+
"value": {
1093+
"success": true,
1094+
"activity_id": "pLAr-Hnq9ZFW4sxlk43Lhbuok4GLh7UW",
1095+
"devices_notified": 2,
1096+
"users_notified": 1,
1097+
"tags": ["user:382", "database-backup"],
1098+
"timestamp": "2026-01-28T09:57:22.929Z"
1099+
}
10211100
}
10221101
}
10231102
}
@@ -1034,6 +1113,13 @@
10341113
"error": "Invalid channel targeting",
10351114
"message": "target.channels must be an array of channel slugs"
10361115
}
1116+
},
1117+
"invalid_tags": {
1118+
"value": {
1119+
"error": "Invalid tags",
1120+
"code": "invalid_tags",
1121+
"message": "tags must use 1-64 lowercase letters, numbers, dashes, underscores, periods, or colons"
1122+
}
10371123
}
10381124
}
10391125
}
@@ -2111,7 +2197,7 @@
21112197
"url": {
21122198
"type": "string",
21132199
"format": "uri",
2114-
"description": "Action URL. For open_url, use an HTTPS URL or a shortcuts://run-shortcut?name=... URL that runs a specific iPhone Shortcut. For webhook, use an HTTPS URL called by the ActivitySmith backend."
2200+
"description": "Action URL. For open_url, use an HTTP or HTTPS URL or a shortcuts://run-shortcut?name=... URL that runs a specific iPhone Shortcut. For webhook, use an HTTPS URL called by the ActivitySmith backend."
21152201
},
21162202
"method": {
21172203
"$ref": "#/components/schemas/PushNotificationWebhookMethod",
@@ -2137,7 +2223,7 @@
21372223
"then": {
21382224
"properties": {
21392225
"url": {
2140-
"pattern": "^(https|shortcuts)://"
2226+
"pattern": "^(http|https|shortcuts)://"
21412227
}
21422228
}
21432229
}
@@ -2183,7 +2269,7 @@
21832269
"url": {
21842270
"type": "string",
21852271
"format": "uri",
2186-
"description": "Action URL. For open_url, use an HTTPS URL or a shortcuts://run-shortcut?name=... URL that runs a specific iPhone Shortcut. For webhook, use an HTTPS URL called by the ActivitySmith backend."
2272+
"description": "Action URL. For open_url, use an HTTP or HTTPS URL or a shortcuts://run-shortcut?name=... URL that runs a specific iPhone Shortcut. For webhook, use an HTTPS URL called by the ActivitySmith backend."
21872273
},
21882274
"method": {
21892275
"$ref": "#/components/schemas/LiveActivityWebhookMethod",
@@ -2209,7 +2295,7 @@
22092295
"then": {
22102296
"properties": {
22112297
"url": {
2212-
"pattern": "^(https|shortcuts)://"
2298+
"pattern": "^(http|https|shortcuts)://"
22132299
}
22142300
}
22152301
}
@@ -2268,6 +2354,19 @@
22682354
"required": ["success", "badge", "devices_notified", "users_notified", "effective_channel_slugs", "timestamp"],
22692355
"additionalProperties": false
22702356
},
2357+
"TagSlugs": {
2358+
"type": "array",
2359+
"description": "Optional tags to organize and filter notification history.",
2360+
"items": {
2361+
"type": "string",
2362+
"minLength": 1,
2363+
"maxLength": 64,
2364+
"pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]{0,63}$"
2365+
},
2366+
"examples": [
2367+
["user:382", "environment:production"]
2368+
]
2369+
},
22712370
"PushNotificationRequest": {
22722371
"type": "object",
22732372
"required": ["title"],
@@ -2284,8 +2383,8 @@
22842383
"redirection": {
22852384
"type": "string",
22862385
"format": "uri",
2287-
"pattern": "^(https|shortcuts)://",
2288-
"description": "Optional HTTPS URL or shortcuts://run-shortcut?name=... URL opened when the user taps the notification body. Use shortcuts://run-shortcut?name=... to run a specific iPhone Shortcut that already exists on the user's device. Overrides the default tap target from `media` when both are provided."
2386+
"pattern": "^(http|https|shortcuts)://",
2387+
"description": "Optional HTTP URL, HTTPS URL, or shortcuts://run-shortcut?name=... URL opened when the user taps the notification body. Use shortcuts://run-shortcut?name=... to run a specific iPhone Shortcut that already exists on the user's device. Overrides the default tap target from `media` when both are provided."
22892388
},
22902389
"actions": {
22912390
"type": "array",
@@ -2299,7 +2398,8 @@
22992398
},
23002399
"badge": { "type": "integer" },
23012400
"sound": { "type": "string" },
2302-
"target": { "$ref": "#/components/schemas/ChannelTarget" }
2401+
"target": { "$ref": "#/components/schemas/ChannelTarget" },
2402+
"tags": { "$ref": "#/components/schemas/TagSlugs" }
23032403
},
23042404
"additionalProperties": false
23052405
},
@@ -2313,6 +2413,7 @@
23132413
"type": ["array", "null"],
23142414
"items": { "type": "string" }
23152415
},
2416+
"tags": { "$ref": "#/components/schemas/TagSlugs" },
23162417
"timestamp": { "type": "string", "format": "date-time" }
23172418
},
23182419
"required": ["success", "timestamp"],
@@ -2330,7 +2431,8 @@
23302431
"description": "Optional secondary action button. Supported for alert, progress, and segmented_progress Live Activities. Uses the same open_url, shortcuts://, and webhook shapes as action."
23312432
},
23322433
"alert": { "$ref": "#/components/schemas/AlertPayload" },
2333-
"target": { "$ref": "#/components/schemas/ChannelTarget" }
2434+
"target": { "$ref": "#/components/schemas/ChannelTarget" },
2435+
"tags": { "$ref": "#/components/schemas/TagSlugs" }
23342436
},
23352437
"additionalProperties": false
23362438
},
@@ -2346,6 +2448,7 @@
23462448
"type": ["array", "null"],
23472449
"items": { "type": "string" }
23482450
},
2451+
"tags": { "$ref": "#/components/schemas/TagSlugs" },
23492452
"timestamp": { "type": "string", "format": "date-time" }
23502453
},
23512454
"required": ["success", "activity_id", "timestamp"],
@@ -2369,7 +2472,11 @@
23692472
"minItems": 1,
23702473
"description": "Channel slugs. When omitted, API key scope determines recipients."
23712474
},
2372-
"target": { "$ref": "#/components/schemas/ChannelTarget" }
2475+
"target": { "$ref": "#/components/schemas/ChannelTarget" },
2476+
"tags": {
2477+
"$ref": "#/components/schemas/TagSlugs",
2478+
"description": "Optional tags to organize and filter notification history. Omit this field on later updates to keep the current tags, send tags again to replace them, or send an empty array to clear them."
2479+
}
23732480
},
23742481
"additionalProperties": false
23752482
},
@@ -2392,6 +2499,7 @@
23922499
"type": ["array", "null"],
23932500
"items": { "type": "string" }
23942501
},
2502+
"tags": { "$ref": "#/components/schemas/TagSlugs" },
23952503
"timestamp": { "type": "string", "format": "date-time" }
23962504
},
23972505
"required": ["success", "operation", "stream_key", "timestamp"],

0 commit comments

Comments
 (0)