2026-08-12 18:23:57 +08:00
openapi : 3.0.3
info :
title : IAM Notification Center API
version : 1.0.0
2026-08-12 18:49:46 +08:00
description : First release supports IN_APP only and does not support deleting or clearing read messages.
servers : [ {url : /api}]
2026-08-12 18:23:57 +08:00
tags :
2026-08-12 18:49:46 +08:00
- {name : Notification inbox}
- {name : Platform notification administration}
2026-08-12 18:23:57 +08:00
paths :
/{app}/v1/notifications:
get :
tags : [ Notification inbox]
summary : List current user's inbox
parameters :
2026-08-12 18:49:46 +08:00
- {$ref : '#/components/parameters/AppPath' }
- {$ref : '#/components/parameters/Page' }
- {$ref : '#/components/parameters/Size' }
2026-08-12 18:23:57 +08:00
- {name : status, in : query, schema : {type : string, enum : [ UNREAD, READ]}}
- {name : category, in : query, schema : {type : string, maxLength : 64 }}
2026-08-12 18:49:46 +08:00
responses : {'200' : {$ref : '#/components/responses/InboxPage' }}
2026-08-12 18:23:57 +08:00
/{app}/v1/notifications/unread-count:
get :
tags : [ Notification inbox]
2026-08-12 18:49:46 +08:00
summary : Count current user's unread messages
parameters : [ {$ref : '#/components/parameters/AppPath' }]
responses : {'200' : {$ref : '#/components/responses/UnreadCount' }}
2026-08-12 18:23:57 +08:00
/{app}/v1/notifications/{id}:
get :
tags : [ Notification inbox]
summary : Get one inbox message
2026-08-12 18:49:46 +08:00
parameters : [ {$ref : '#/components/parameters/AppPath' }, {$ref : '#/components/parameters/IdPath' }]
responses : {'200' : {$ref : '#/components/responses/InboxDetail' }}
2026-08-12 18:23:57 +08:00
/{app}/v1/notifications/{id}/read:
put :
tags : [ Notification inbox]
summary : Mark one message as read (idempotent)
2026-08-12 18:49:46 +08:00
parameters : [ {$ref : '#/components/parameters/AppPath' }, {$ref : '#/components/parameters/IdPath' }]
responses : {'200' : {$ref : '#/components/responses/InboxDetail' }}
2026-08-12 18:23:57 +08:00
/{app}/v1/notifications/read-all:
put :
tags : [ Notification inbox]
summary : Mark all current-user messages as read (idempotent)
2026-08-12 18:49:46 +08:00
parameters : [ {$ref : '#/components/parameters/AppPath' }]
responses : {'200' : {$ref : '#/components/responses/ReadAll' }}
2026-08-12 18:23:57 +08:00
/platform/v1/notifications :
post :
tags : [ Platform notification administration]
2026-08-12 18:49:46 +08:00
summary : Create an IN_APP notification task
requestBody : {$ref : '#/components/requestBodies/CreateNotification' }
responses : {'200' : {$ref : '#/components/responses/TaskDetail' }}
2026-08-12 18:23:57 +08:00
/platform/v1/notification-templates :
get :
tags : [ Platform notification administration]
summary : List templates
2026-08-12 18:49:46 +08:00
parameters :
- {$ref : '#/components/parameters/Page' }
- {$ref : '#/components/parameters/Size' }
- {name : templateCode, in : query, schema : {type : string, maxLength : 64 }}
- {name : category, in : query, schema : {type : string, maxLength : 64 }}
- {name : title, in : query, description : Fuzzy match template name or title template, schema : {type : string, maxLength : 128 }}
- {name : status, in : query, schema : {type : string, enum : [ DRAFT, ACTIVE, DISABLED]}}
responses : {'200' : {$ref : '#/components/responses/TemplatePage' }}
2026-08-12 18:23:57 +08:00
post :
tags : [ Platform notification administration]
summary : Create a DRAFT template
2026-08-12 18:49:46 +08:00
requestBody : {$ref : '#/components/requestBodies/CreateTemplate' }
responses : {'200' : {$ref : '#/components/responses/TemplateDetail' }}
2026-08-12 18:23:57 +08:00
/platform/v1/notification-templates/{id}:
put :
tags : [ Platform notification administration]
summary : Edit a DRAFT template only
2026-08-12 18:49:46 +08:00
parameters : [ {$ref : '#/components/parameters/IdPath' }]
requestBody : {$ref : '#/components/requestBodies/UpdateTemplate' }
responses : {'200' : {$ref : '#/components/responses/TemplateDetail' }}
2026-08-12 18:23:57 +08:00
/platform/v1/notification-templates/{id}/status:
put :
tags : [ Platform notification administration]
2026-08-12 18:49:46 +08:00
summary : Change template status
description : Only DRAFT to ACTIVE and ACTIVE to DISABLED are valid. DISABLED cannot return to ACTIVE; copy it to a new DRAFT instead.
parameters : [ {$ref : '#/components/parameters/IdPath' }]
requestBody : {$ref : '#/components/requestBodies/ChangeTemplateStatus' }
responses : {'200' : {$ref : '#/components/responses/TemplateDetail' }}
2026-08-12 18:23:57 +08:00
/platform/v1/notification-tasks :
get :
tags : [ Platform notification administration]
2026-08-12 18:49:46 +08:00
summary : List notification tasks
parameters :
- {$ref : '#/components/parameters/Page' }
- {$ref : '#/components/parameters/Size' }
- {name : taskNo, in : query, schema : {type : string, maxLength : 64 }}
- {name : category, in : query, schema : {type : string, maxLength : 64 }}
- {name : title, in : query, description : Fuzzy match rendered title, schema : {type : string, maxLength : 128 }}
- {name : status, in : query, schema : {type : string, enum : [ CREATED, SCHEDULED, DISPATCHING, RETRYING, SENT, DEAD, CANCELLED]}}
responses : {'200' : {$ref : '#/components/responses/TaskPage' }}
2026-08-12 18:23:57 +08:00
/platform/v1/notification-tasks/{id}/cancel:
put :
tags : [ Platform notification administration]
2026-08-12 18:49:46 +08:00
summary : Cancel a CREATED or SCHEDULED task
parameters : [ {$ref : '#/components/parameters/IdPath' }]
responses : {'200' : {$ref : '#/components/responses/TaskDetail' }}
2026-08-12 18:23:57 +08:00
/platform/v1/notification-tasks/{id}/retry:
put :
tags : [ Platform notification administration]
2026-08-12 18:49:46 +08:00
summary : Retry a RETRYING or DEAD task
parameters : [ {$ref : '#/components/parameters/IdPath' }]
responses : {'200' : {$ref : '#/components/responses/TaskDetail' }}
2026-08-12 18:23:57 +08:00
components :
2026-08-12 18:49:46 +08:00
parameters :
AppPath : {name : app, in : path, required : true, schema : {type : string, enum : [ platform, merchant]}}
IdPath : {name : id, in : path, required : true, schema : {type : integer, format : int64}}
Page : {name : page, in : query, schema : {type : integer, minimum : 1, default : 1 }}
Size : {name : size, in : query, schema : {type : integer, minimum : 1, maximum : 200, default : 20 }}
requestBodies :
CreateNotification : {required : true, content : {application/json : {schema : {$ref : '#/components/schemas/CreateNotificationRequest' }}}}
CreateTemplate : {required : true, content : {application/json : {schema : {$ref : '#/components/schemas/CreateTemplateRequest' }}}}
UpdateTemplate : {required : true, content : {application/json : {schema : {$ref : '#/components/schemas/UpdateTemplateRequest' }}}}
ChangeTemplateStatus : {required : true, content : {application/json : {schema : {$ref : '#/components/schemas/ChangeTemplateStatusRequest' }}}}
responses :
InboxPage : {description : OK, content : {application/json : {schema : {$ref : '#/components/schemas/InboxPageResponse' }}}}
InboxDetail : {description : OK, content : {application/json : {schema : {$ref : '#/components/schemas/InboxDetailResponse' }}}}
UnreadCount : {description : OK, content : {application/json : {schema : {$ref : '#/components/schemas/UnreadCountResponse' }}}}
ReadAll : {description : OK, content : {application/json : {schema : {$ref : '#/components/schemas/ReadAllResponse' }}}}
TemplatePage : {description : OK, content : {application/json : {schema : {$ref : '#/components/schemas/TemplatePageResponse' }}}}
TemplateDetail : {description : OK, content : {application/json : {schema : {$ref : '#/components/schemas/TemplateDetailResponse' }}}}
TaskPage : {description : OK, content : {application/json : {schema : {$ref : '#/components/schemas/TaskPageResponse' }}}}
TaskDetail : {description : OK, content : {application/json : {schema : {$ref : '#/components/schemas/TaskDetailResponse' }}}}
2026-08-12 18:23:57 +08:00
schemas :
2026-08-12 18:49:46 +08:00
CreateNotificationRequest :
type : object
required : [ tenantId, templateCode, recipientType, variables, idempotencyKey]
description : tenantId is a backend compatibility field. 0 means platform scope and a positive value is the customer (enterprise) ID; UI copy must use customer or enterprise, never tenant.
properties :
tenantId : {type : integer, format : int64, minimum : 0 }
templateCode : {type : string, maxLength : 64 }
recipientType : {type : string, enum : [ USER, MEMBERSHIP, TENANT_ROLE, TENANT_ALL, PLATFORM_ROLE]}
recipientIds : {type : array, maxItems : 1000, items : {type : integer, format : int64}, description : Required for USER or MEMBERSHIP; forbidden for role/all recipient types.}
roleCode : {type : string, maxLength : 64, description : Required for TENANT_ROLE or PLATFORM_ROLE; forbidden otherwise.}
variables : {type : object, maxProperties : 32, additionalProperties : {type : string, maxLength : 2000 }}
scheduledAt : {type : string, format : date-time, nullable : true }
idempotencyKey : {type : string, minLength : 8, maxLength : 128 }
sourceEventId : {type : string, maxLength : 128, nullable : true }
allOf :
- if : {properties : {recipientType : {enum : [ USER, MEMBERSHIP]}}}
then : {required : [ recipientIds]}
- if : {properties : {recipientType : {enum : [ TENANT_ROLE, PLATFORM_ROLE]}}}
then : {required : [ roleCode]}
CreateTemplateRequest :
type : object
required : [ templateCode, templateName, category, titleTemplate, bodyTemplate, variableWhitelist]
properties : {templateCode : {type : string, pattern : '^[A-Z][A-Z0-9_]{0,63}$' }, templateName : {type : string, maxLength : 128}, category : {type : string, maxLength : 64}, titleTemplate : {type : string, maxLength : 256}, bodyTemplate : {type : string, maxLength : 10000}, variableWhitelist : {type : array, maxItems : 32, uniqueItems : true, items : {type : string, pattern : '^[a-z][a-z0-9_]{0,31}$' }}}
UpdateTemplateRequest :
type : object
required : [ templateName, category, titleTemplate, bodyTemplate, variableWhitelist, version]
properties : {templateName : {type : string, maxLength : 128}, category : {type : string, maxLength : 64}, titleTemplate : {type : string, maxLength : 256}, bodyTemplate : {type : string, maxLength : 10000}, variableWhitelist : {type : array, maxItems : 32, uniqueItems : true, items : {type : string, pattern : '^[a-z][a-z0-9_]{0,31}$' }}, version : {type : integer, minimum : 1 }}
ChangeTemplateStatusRequest :
type : object
required : [ targetStatus, version]
properties : {targetStatus : {type : string, enum : [ACTIVE, DISABLED], description : ACTIVE is accepted only from DRAFT; DISABLED only from ACTIVE.}, version : {type : integer, minimum : 1 }}
InboxItem : {type : object, required : [id, category, title, status, sentAt], properties : {id : {type : integer, format : int64}, category : {type : string}, title : {type : string}, status : {type : string, enum : [UNREAD, READ]}, sentAt : {type : string, format : date-time}, readAt : {type : string, format : date-time, nullable : true }}}
InboxDetail : {allOf : [ {$ref : '#/components/schemas/InboxItem' }, {type : object, required : [body], properties : {body : {type : string}, sourceType : {type : string, nullable : true}, sourceId : {type : string, nullable : true }}}] }
TemplateItem : {type : object, required : [id, templateCode, templateName, category, channel, titleTemplate, bodyTemplate, variableWhitelist, status, version], properties : {id : {type : integer, format : int64}, templateCode : {type : string}, templateName : {type : string}, category : {type : string}, channel : {type : string, enum : [IN_APP]}, titleTemplate : {type : string}, bodyTemplate : {type : string}, variableWhitelist : {type : array, items : {type : string}}, status : {type : string, enum : [DRAFT, ACTIVE, DISABLED]}, version : {type : integer}}}
TaskItem : {type : object, required : [id, taskNo, category, title, status, recipientCount, duplicated], properties : {id : {type : integer, format : int64}, taskNo : {type : string}, category : {type : string}, title : {type : string}, status : {type : string, enum : [CREATED, SCHEDULED, DISPATCHING, RETRYING, SENT, DEAD, CANCELLED]}, recipientCount : {type : integer}, scheduledAt : {type : string, format : date-time, nullable : true}, sentAt : {type : string, format : date-time, nullable : true}, duplicated : {type : boolean}}}
InboxPageData : {type : object, required : [records, page, size, total, pages], properties : {records : {type : array, items : {$ref : '#/components/schemas/InboxItem' }}, page : {type : integer}, size : {type : integer}, total : {type : integer}, pages : {type : integer}}}
TemplatePageData : {type : object, required : [records, page, size, total, pages], properties : {records : {type : array, items : {$ref : '#/components/schemas/TemplateItem' }}, page : {type : integer}, size : {type : integer}, total : {type : integer}, pages : {type : integer}}}
TaskPageData : {type : object, required : [records, page, size, total, pages], properties : {records : {type : array, items : {$ref : '#/components/schemas/TaskItem' }}, page : {type : integer}, size : {type : integer}, total : {type : integer}, pages : {type : integer}}}
InboxPageResponse : {type : object, required : [code, data], properties : {code : {type : string, example : '200'}, data : {$ref : '#/components/schemas/InboxPageData' }}}
InboxDetailResponse : {type : object, required : [code, data], properties : {code : {type : string, example : '200'}, data : {$ref : '#/components/schemas/InboxDetail' }}}
UnreadCountResponse : {type : object, required : [code, data], properties : {code : {type : string, example : '200'}, data : {type : object, required : [unreadCount], properties : {unreadCount : {type : integer, format : int64}}}}}
ReadAllResponse : {type : object, required : [code, data], properties : {code : {type : string, example : '200'}, data : {type : object, required : [updatedCount], properties : {updatedCount : {type : integer, format : int64}}}}}
TemplatePageResponse : {type : object, required : [code, data], properties : {code : {type : string, example : '200'}, data : {$ref : '#/components/schemas/TemplatePageData' }}}
TemplateDetailResponse : {type : object, required : [code, data], properties : {code : {type : string, example : '200'}, data : {$ref : '#/components/schemas/TemplateItem' }}}
TaskPageResponse : {type : object, required : [code, data], properties : {code : {type : string, example : '200'}, data : {$ref : '#/components/schemas/TaskPageData' }}}
TaskDetailResponse : {type : object, required : [code, data], properties : {code : {type : string, example : '200'}, data : {$ref : '#/components/schemas/TaskItem' }}}