1077 lines
30 KiB
YAML
1077 lines
30 KiB
YAML
openapi: 3.1.0
|
|
info:
|
|
title: Member Center API
|
|
version: 0.1.0
|
|
description: OAuth2/OIDC + Newsletter Subscription API
|
|
servers:
|
|
- url: /
|
|
security:
|
|
- BearerAuth: []
|
|
|
|
paths:
|
|
/oauth/authorize:
|
|
get:
|
|
summary: OAuth2 Authorization Endpoint
|
|
description: Authorization Code + PKCE flow
|
|
security: []
|
|
parameters:
|
|
- in: query
|
|
name: client_id
|
|
required: true
|
|
schema: { type: string }
|
|
- in: query
|
|
name: redirect_uri
|
|
required: true
|
|
schema: { type: string }
|
|
- in: query
|
|
name: response_type
|
|
required: true
|
|
schema: { type: string, enum: [code] }
|
|
- in: query
|
|
name: scope
|
|
required: true
|
|
schema: { type: string }
|
|
- in: query
|
|
name: code_challenge
|
|
required: true
|
|
schema: { type: string }
|
|
- in: query
|
|
name: code_challenge_method
|
|
required: true
|
|
schema: { type: string, enum: [S256] }
|
|
- in: query
|
|
name: state
|
|
required: false
|
|
schema: { type: string }
|
|
responses:
|
|
'302':
|
|
description: Redirect to client with code
|
|
|
|
/oauth/token:
|
|
post:
|
|
summary: OAuth2 Token Endpoint
|
|
security: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/x-www-form-urlencoded:
|
|
schema:
|
|
oneOf:
|
|
- $ref: '#/components/schemas/AuthorizationCodeTokenRequest'
|
|
- $ref: '#/components/schemas/RefreshTokenRequest'
|
|
- $ref: '#/components/schemas/ClientCredentialsTokenRequest'
|
|
responses:
|
|
'200':
|
|
description: Token response
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/TokenResponse'
|
|
|
|
/.well-known/openid-configuration:
|
|
get:
|
|
summary: OIDC Discovery
|
|
responses:
|
|
'200':
|
|
description: OIDC discovery document
|
|
|
|
/.well-known/jwks:
|
|
get:
|
|
summary: JWKS
|
|
responses:
|
|
'200':
|
|
description: JSON Web Key Set
|
|
|
|
/auth/register:
|
|
post:
|
|
summary: Register user
|
|
security: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/RegisterRequest'
|
|
responses:
|
|
'200':
|
|
description: Registered
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/UserProfile'
|
|
|
|
/auth/login:
|
|
post:
|
|
summary: API login
|
|
security: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/x-www-form-urlencoded:
|
|
schema:
|
|
$ref: '#/components/schemas/PasswordTokenRequest'
|
|
responses:
|
|
'200':
|
|
description: Token response
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/TokenResponse'
|
|
|
|
/auth/refresh:
|
|
post:
|
|
summary: Refresh token
|
|
security: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/x-www-form-urlencoded:
|
|
schema:
|
|
$ref: '#/components/schemas/RefreshTokenRequest'
|
|
responses:
|
|
'200':
|
|
description: Token response
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/TokenResponse'
|
|
|
|
/auth/logout:
|
|
post:
|
|
summary: Logout (revoke refresh token)
|
|
security:
|
|
- BearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
refresh_token:
|
|
type: string
|
|
responses:
|
|
'204':
|
|
description: Logged out
|
|
|
|
/auth/password/forgot:
|
|
post:
|
|
summary: Request password reset
|
|
security: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ForgotPasswordRequest'
|
|
responses:
|
|
'204':
|
|
description: Email sent
|
|
|
|
/auth/password/reset:
|
|
post:
|
|
summary: Reset password
|
|
security: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ResetPasswordRequest'
|
|
responses:
|
|
'204':
|
|
description: Password reset
|
|
|
|
/auth/email/verify:
|
|
get:
|
|
summary: Verify email
|
|
security: []
|
|
parameters:
|
|
- in: query
|
|
name: token
|
|
required: true
|
|
schema: { type: string }
|
|
- in: query
|
|
name: email
|
|
required: true
|
|
schema: { type: string, format: email }
|
|
responses:
|
|
'200':
|
|
description: Email verified
|
|
|
|
/user/profile:
|
|
get:
|
|
summary: Get current user profile
|
|
security:
|
|
- BearerAuth: []
|
|
responses:
|
|
'200':
|
|
description: Profile
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/UserProfile'
|
|
|
|
/newsletter/subscribe:
|
|
post:
|
|
summary: Subscribe (unauthenticated allowed)
|
|
security: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SubscribeRequest'
|
|
responses:
|
|
'200':
|
|
description: Pending subscription
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/PendingSubscriptionResponse'
|
|
'400':
|
|
description: Bad request
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
'404':
|
|
description: Not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
/newsletter/confirm:
|
|
get:
|
|
summary: Confirm subscription (double opt-in)
|
|
security: []
|
|
parameters:
|
|
- in: query
|
|
name: token
|
|
required: true
|
|
schema: { type: string }
|
|
responses:
|
|
'200':
|
|
description: Active subscription
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Subscription'
|
|
'400':
|
|
description: Bad request
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
'404':
|
|
description: Not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
/newsletter/unsubscribe:
|
|
post:
|
|
summary: Unsubscribe single list
|
|
security: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [token]
|
|
properties:
|
|
token: { type: string }
|
|
responses:
|
|
'200':
|
|
description: Unsubscribed
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Subscription'
|
|
'400':
|
|
description: Bad request
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
'404':
|
|
description: Not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
/newsletter/unsubscribe-token:
|
|
post:
|
|
summary: Issue unsubscribe token
|
|
security: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [list_id, email]
|
|
properties:
|
|
list_id: { type: string }
|
|
email: { type: string, format: email }
|
|
responses:
|
|
'200':
|
|
description: Unsubscribe token issued
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
unsubscribe_token: { type: string }
|
|
'400':
|
|
description: Bad request
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
'404':
|
|
description: Not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
/newsletter/one-click-unsubscribe-token:
|
|
post:
|
|
summary: Issue one-click unsubscribe token (Send Engine pre-send)
|
|
security: [{ BearerAuth: [] }]
|
|
description: Requires scope `newsletter:events.write` or `newsletter:events.write.global`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/IssueOneClickUnsubscribeTokenRequest'
|
|
responses:
|
|
'200':
|
|
description: Unsubscribe token issued
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
unsubscribe_token: { type: string }
|
|
'400':
|
|
description: Bad request
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
'401':
|
|
description: Unauthorized
|
|
'403':
|
|
description: Forbidden
|
|
'404':
|
|
description: Not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
/newsletter/one-click-unsubscribe-tokens:
|
|
post:
|
|
summary: Issue one-click unsubscribe tokens in batch (Send Engine pre-send)
|
|
security: [{ BearerAuth: [] }]
|
|
description: Requires scope `newsletter:events.write` or `newsletter:events.write.global`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/IssueOneClickUnsubscribeTokensRequest'
|
|
responses:
|
|
'200':
|
|
description: Unsubscribe tokens issued
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
items:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/OneClickUnsubscribeTokenItem'
|
|
'400':
|
|
description: Bad request
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
'401':
|
|
description: Unauthorized
|
|
'403':
|
|
description: Forbidden
|
|
|
|
/newsletter/preferences:
|
|
get:
|
|
summary: Get preferences
|
|
parameters:
|
|
- in: query
|
|
name: list_id
|
|
required: true
|
|
schema: { type: string }
|
|
- in: query
|
|
name: email
|
|
required: true
|
|
schema: { type: string, format: email }
|
|
responses:
|
|
'200':
|
|
description: Preferences
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Subscription'
|
|
'400':
|
|
description: Bad request
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
'404':
|
|
description: Not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
post:
|
|
summary: Update preferences
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [list_id, email, preferences]
|
|
properties:
|
|
list_id: { type: string }
|
|
email: { type: string, format: email }
|
|
preferences: { type: object }
|
|
responses:
|
|
'200':
|
|
description: Updated
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Subscription'
|
|
'400':
|
|
description: Bad request
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
'404':
|
|
description: Not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
/newsletter/subscriptions:
|
|
get:
|
|
summary: List subscriptions by list
|
|
security: [{ BearerAuth: [] }]
|
|
description: Requires scope `newsletter:list.read`.
|
|
parameters:
|
|
- in: query
|
|
name: list_id
|
|
required: true
|
|
schema: { type: string }
|
|
responses:
|
|
'200':
|
|
description: List
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Subscription'
|
|
'400':
|
|
description: Bad request
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
'404':
|
|
description: Not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
/subscriptions/disable:
|
|
post:
|
|
summary: Disable subscription / blacklist by reason
|
|
security: [{ BearerAuth: [] }]
|
|
description: |
|
|
Requires scope `newsletter:events.write` (tenant client) or `newsletter:events.write.global` (platform client).
|
|
Request must include `tenant_id`, `subscriber_id`, and `list_id` for tenant-boundary validation.
|
|
Reason handling:
|
|
- `hard_bounce`, `soft_bounce_threshold`, `suppression`: unsubscribe all subscriptions for the email across tenants + add to global blacklist.
|
|
- `complaint`: unsubscribe only the target subscription, no blacklist.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/DisableSubscriptionRequest'
|
|
responses:
|
|
'200':
|
|
description: Disabled
|
|
'400':
|
|
description: Bad request
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
'404':
|
|
description: Not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
/integrations/send-engine/webhook-clients/upsert:
|
|
post:
|
|
summary: Upsert Send Engine webhook client mapping for tenant
|
|
security: [{ BearerAuth: [] }]
|
|
description: Requires scope `newsletter:events.write.global`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/UpsertSendEngineWebhookClientRequest'
|
|
responses:
|
|
'200':
|
|
description: Updated
|
|
'400':
|
|
description: Bad request
|
|
'401':
|
|
description: Unauthorized
|
|
'403':
|
|
description: Forbidden
|
|
'404':
|
|
description: Tenant not found
|
|
|
|
/webhooks/subscriptions:
|
|
post:
|
|
summary: (NOTE) Member Center -> Send Engine subscription events webhook
|
|
description: This endpoint is implemented by Send Engine; listed here as an integration note. Required headers are X-Signature, X-Timestamp, X-Nonce, X-Client-Id. X-Client-Id must be Send Engine `auth_clients.id` (UUID), tenant-bound, no fallback client id.
|
|
security: []
|
|
parameters:
|
|
- in: header
|
|
name: X-Signature
|
|
required: true
|
|
schema: { type: string }
|
|
- in: header
|
|
name: X-Timestamp
|
|
required: true
|
|
schema: { type: string }
|
|
- in: header
|
|
name: X-Nonce
|
|
required: true
|
|
schema: { type: string, format: uuid }
|
|
- in: header
|
|
name: X-Client-Id
|
|
required: true
|
|
schema: { type: string }
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SendEngineSubscriptionEvent'
|
|
responses:
|
|
'200':
|
|
description: Accepted
|
|
|
|
/webhooks/lists/full-sync:
|
|
post:
|
|
summary: (NOTE) Member Center -> Send Engine full list sync webhook
|
|
description: This endpoint is implemented by Send Engine; listed here as an integration note. Required headers are X-Signature, X-Timestamp, X-Nonce, X-Client-Id. X-Client-Id must be Send Engine `auth_clients.id` (UUID), tenant-bound, no fallback client id.
|
|
security: []
|
|
parameters:
|
|
- in: header
|
|
name: X-Signature
|
|
required: true
|
|
schema: { type: string }
|
|
- in: header
|
|
name: X-Timestamp
|
|
required: true
|
|
schema: { type: string }
|
|
- in: header
|
|
name: X-Nonce
|
|
required: true
|
|
schema: { type: string, format: uuid }
|
|
- in: header
|
|
name: X-Client-Id
|
|
required: true
|
|
schema: { type: string }
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SendEngineListFullSync'
|
|
responses:
|
|
'200':
|
|
description: Accepted
|
|
|
|
/admin/tenants:
|
|
get:
|
|
summary: List tenants
|
|
security: [{ BearerAuth: [] }]
|
|
responses:
|
|
'200':
|
|
description: List
|
|
post:
|
|
summary: Create tenant
|
|
security: [{ BearerAuth: [] }]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Tenant'
|
|
responses:
|
|
'201':
|
|
description: Created
|
|
|
|
/admin/tenants/{id}:
|
|
get:
|
|
summary: Get tenant
|
|
security: [{ BearerAuth: [] }]
|
|
parameters:
|
|
- in: path
|
|
name: id
|
|
required: true
|
|
schema: { type: string }
|
|
responses:
|
|
'200':
|
|
description: Tenant
|
|
put:
|
|
summary: Update tenant
|
|
security: [{ BearerAuth: [] }]
|
|
parameters:
|
|
- in: path
|
|
name: id
|
|
required: true
|
|
schema: { type: string }
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Tenant'
|
|
responses:
|
|
'200':
|
|
description: Updated
|
|
delete:
|
|
summary: Delete tenant
|
|
security: [{ BearerAuth: [] }]
|
|
parameters:
|
|
- in: path
|
|
name: id
|
|
required: true
|
|
schema: { type: string }
|
|
responses:
|
|
'204':
|
|
description: Deleted
|
|
|
|
/admin/newsletter-lists:
|
|
get:
|
|
summary: List newsletter lists
|
|
security: [{ BearerAuth: [] }]
|
|
responses:
|
|
'200':
|
|
description: List
|
|
post:
|
|
summary: Create list
|
|
security: [{ BearerAuth: [] }]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/NewsletterList'
|
|
responses:
|
|
'201':
|
|
description: Created
|
|
|
|
/admin/newsletter-lists/{id}:
|
|
get:
|
|
summary: Get list
|
|
security: [{ BearerAuth: [] }]
|
|
parameters:
|
|
- in: path
|
|
name: id
|
|
required: true
|
|
schema: { type: string }
|
|
responses:
|
|
'200':
|
|
description: List
|
|
put:
|
|
summary: Update list
|
|
security: [{ BearerAuth: [] }]
|
|
parameters:
|
|
- in: path
|
|
name: id
|
|
required: true
|
|
schema: { type: string }
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/NewsletterList'
|
|
responses:
|
|
'200':
|
|
description: Updated
|
|
delete:
|
|
summary: Delete list
|
|
security: [{ BearerAuth: [] }]
|
|
parameters:
|
|
- in: path
|
|
name: id
|
|
required: true
|
|
schema: { type: string }
|
|
responses:
|
|
'204':
|
|
description: Deleted
|
|
|
|
/admin/oauth-clients:
|
|
get:
|
|
summary: List OAuth clients
|
|
security: [{ BearerAuth: [] }]
|
|
responses:
|
|
'200':
|
|
description: List
|
|
post:
|
|
summary: Create OAuth client
|
|
security: [{ BearerAuth: [] }]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/OAuthClient'
|
|
responses:
|
|
'201':
|
|
description: Created
|
|
|
|
/admin/oauth-clients/{id}:
|
|
get:
|
|
summary: Get OAuth client
|
|
security: [{ BearerAuth: [] }]
|
|
parameters:
|
|
- in: path
|
|
name: id
|
|
required: true
|
|
schema: { type: string }
|
|
responses:
|
|
'200':
|
|
description: OAuth client
|
|
put:
|
|
summary: Update OAuth client
|
|
security: [{ BearerAuth: [] }]
|
|
parameters:
|
|
- in: path
|
|
name: id
|
|
required: true
|
|
schema: { type: string }
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/OAuthClient'
|
|
responses:
|
|
'200':
|
|
description: Updated
|
|
delete:
|
|
summary: Delete OAuth client
|
|
security: [{ BearerAuth: [] }]
|
|
parameters:
|
|
- in: path
|
|
name: id
|
|
required: true
|
|
schema: { type: string }
|
|
responses:
|
|
'204':
|
|
description: Deleted
|
|
|
|
components:
|
|
securitySchemes:
|
|
OAuth2:
|
|
type: oauth2
|
|
flows:
|
|
authorizationCode:
|
|
authorizationUrl: /oauth/authorize
|
|
tokenUrl: /oauth/token
|
|
scopes:
|
|
openid: OpenID Connect
|
|
email: Email
|
|
profile: Basic profile
|
|
newsletter:list.read: Read newsletter subscriptions by list
|
|
newsletter:send.write: Create/send newsletter jobs
|
|
newsletter:send.read: Read newsletter send status
|
|
newsletter:events.read: Read newsletter events
|
|
newsletter:events.write: Write newsletter events (tenant scoped)
|
|
newsletter:events.write.global: Write newsletter events (platform scoped)
|
|
clientCredentials:
|
|
tokenUrl: /oauth/token
|
|
scopes:
|
|
newsletter:list.read: Read newsletter subscriptions by list
|
|
newsletter:send.write: Create/send newsletter jobs
|
|
newsletter:send.read: Read newsletter send status
|
|
newsletter:events.read: Read newsletter events
|
|
newsletter:events.write: Write newsletter events (tenant scoped)
|
|
newsletter:events.write.global: Write newsletter events (platform scoped)
|
|
BearerAuth:
|
|
type: http
|
|
scheme: bearer
|
|
bearerFormat: JWT
|
|
|
|
schemas:
|
|
TokenResponse:
|
|
type: object
|
|
properties:
|
|
access_token: { type: string }
|
|
refresh_token: { type: string }
|
|
id_token: { type: string }
|
|
token_type: { type: string, example: Bearer }
|
|
expires_in: { type: integer }
|
|
|
|
RegisterRequest:
|
|
type: object
|
|
required: [email, password]
|
|
properties:
|
|
email: { type: string, format: email }
|
|
password: { type: string }
|
|
|
|
PasswordTokenRequest:
|
|
type: object
|
|
required: [grant_type, username, password]
|
|
properties:
|
|
grant_type: { type: string, enum: [password] }
|
|
username: { type: string, format: email }
|
|
password: { type: string }
|
|
scope: { type: string }
|
|
client_id: { type: string }
|
|
|
|
AuthorizationCodeTokenRequest:
|
|
type: object
|
|
required: [grant_type, code, redirect_uri, code_verifier]
|
|
properties:
|
|
grant_type: { type: string, enum: [authorization_code] }
|
|
code: { type: string }
|
|
redirect_uri: { type: string }
|
|
code_verifier: { type: string }
|
|
client_id: { type: string }
|
|
|
|
RefreshRequest:
|
|
type: object
|
|
required: [refresh_token, client_id]
|
|
properties:
|
|
refresh_token: { type: string }
|
|
client_id: { type: string }
|
|
|
|
RefreshTokenRequest:
|
|
type: object
|
|
required: [grant_type, refresh_token]
|
|
properties:
|
|
grant_type: { type: string, enum: [refresh_token] }
|
|
refresh_token: { type: string }
|
|
client_id: { type: string }
|
|
|
|
ClientCredentialsTokenRequest:
|
|
type: object
|
|
required: [grant_type, client_id, client_secret]
|
|
properties:
|
|
grant_type: { type: string, enum: [client_credentials] }
|
|
client_id: { type: string }
|
|
client_secret: { type: string }
|
|
scope: { type: string }
|
|
|
|
ForgotPasswordRequest:
|
|
type: object
|
|
required: [email]
|
|
properties:
|
|
email: { type: string, format: email }
|
|
|
|
ResetPasswordRequest:
|
|
type: object
|
|
required: [email, token, new_password]
|
|
properties:
|
|
email: { type: string, format: email }
|
|
token: { type: string }
|
|
new_password: { type: string }
|
|
|
|
UserProfile:
|
|
type: object
|
|
properties:
|
|
id: { type: string }
|
|
email: { type: string, format: email }
|
|
email_verified: { type: boolean }
|
|
created_at: { type: string, format: date-time }
|
|
|
|
SubscribeRequest:
|
|
type: object
|
|
required: [list_id, email]
|
|
properties:
|
|
list_id: { type: string }
|
|
email: { type: string, format: email }
|
|
preferences: { type: object }
|
|
source: { type: string }
|
|
|
|
Subscription:
|
|
type: object
|
|
properties:
|
|
id: { type: string }
|
|
list_id: { type: string }
|
|
email: { type: string, format: email }
|
|
status: { type: string, enum: [pending, active, unsubscribed] }
|
|
preferences: { type: object }
|
|
created_at: { type: string, format: date-time }
|
|
|
|
PendingSubscriptionResponse:
|
|
allOf:
|
|
- $ref: '#/components/schemas/Subscription'
|
|
- type: object
|
|
properties:
|
|
confirm_token: { type: string }
|
|
|
|
DisableSubscriptionRequest:
|
|
type: object
|
|
required: [tenant_id, subscriber_id, list_id, reason, disabled_by, occurred_at]
|
|
properties:
|
|
tenant_id: { type: string, format: uuid }
|
|
subscriber_id: { type: string, format: uuid }
|
|
list_id: { type: string, format: uuid }
|
|
reason:
|
|
type: string
|
|
enum: [hard_bounce, soft_bounce_threshold, complaint, suppression]
|
|
disabled_by: { type: string }
|
|
occurred_at: { type: string, format: date-time }
|
|
|
|
IssueOneClickUnsubscribeTokenRequest:
|
|
type: object
|
|
required: [tenant_id, list_id, subscriber_id]
|
|
properties:
|
|
tenant_id: { type: string, format: uuid }
|
|
list_id: { type: string, format: uuid }
|
|
subscriber_id: { type: string, format: uuid }
|
|
|
|
IssueOneClickUnsubscribeTokensRequest:
|
|
type: object
|
|
required: [tenant_id, list_id, subscriber_ids]
|
|
properties:
|
|
tenant_id: { type: string, format: uuid }
|
|
list_id: { type: string, format: uuid }
|
|
subscriber_ids:
|
|
type: array
|
|
items: { type: string, format: uuid }
|
|
|
|
OneClickUnsubscribeTokenItem:
|
|
type: object
|
|
properties:
|
|
subscriber_id: { type: string, format: uuid }
|
|
unsubscribe_token: { type: string, nullable: true }
|
|
status: { type: string, enum: [issued, not_found, blacklisted] }
|
|
|
|
ErrorResponse:
|
|
type: object
|
|
required: [error, message, request_id]
|
|
properties:
|
|
error: { type: string }
|
|
message: { type: string }
|
|
request_id: { type: string }
|
|
|
|
SendEngineSubscriptionEvent:
|
|
type: object
|
|
required: [event_id, event_type, tenant_id, list_id, subscriber, occurred_at]
|
|
properties:
|
|
event_id: { type: string }
|
|
event_type: { type: string, enum: [subscription.activated, subscription.unsubscribed, preferences.updated] }
|
|
tenant_id: { type: string }
|
|
list_id: { type: string }
|
|
subscriber:
|
|
type: object
|
|
required: [id, email, status]
|
|
properties:
|
|
id: { type: string }
|
|
email: { type: string, format: email }
|
|
status: { type: string, enum: [pending, active, unsubscribed] }
|
|
preferences: { type: object }
|
|
occurred_at: { type: string, format: date-time }
|
|
|
|
SendEngineListFullSync:
|
|
type: object
|
|
required: [sync_id, batch_no, batch_total, tenant_id, list_id, subscribers, occurred_at]
|
|
properties:
|
|
sync_id: { type: string }
|
|
batch_no: { type: integer }
|
|
batch_total: { type: integer }
|
|
tenant_id: { type: string }
|
|
list_id: { type: string }
|
|
subscribers:
|
|
type: array
|
|
items:
|
|
type: object
|
|
required: [id, email, status]
|
|
properties:
|
|
id: { type: string }
|
|
email: { type: string, format: email }
|
|
status: { type: string, enum: [pending, active, unsubscribed] }
|
|
preferences: { type: object }
|
|
occurred_at: { type: string, format: date-time }
|
|
|
|
Tenant:
|
|
type: object
|
|
properties:
|
|
id: { type: string }
|
|
name: { type: string }
|
|
domains: { type: array, items: { type: string } }
|
|
status: { type: string }
|
|
send_engine_webhook_client_id:
|
|
type: string
|
|
format: uuid
|
|
nullable: true
|
|
|
|
UpsertSendEngineWebhookClientRequest:
|
|
type: object
|
|
required: [tenant_id, webhook_client_id]
|
|
properties:
|
|
tenant_id: { type: string, format: uuid }
|
|
webhook_client_id: { type: string, format: uuid }
|
|
|
|
NewsletterList:
|
|
type: object
|
|
properties:
|
|
id: { type: string }
|
|
tenant_id: { type: string }
|
|
name: { type: string }
|
|
status: { type: string }
|
|
|
|
OAuthClient:
|
|
type: object
|
|
properties:
|
|
id: { type: string }
|
|
tenant_id:
|
|
type: string
|
|
nullable: true
|
|
name: { type: string }
|
|
usage: { type: string, enum: [tenant_api, send_api, webhook_outbound, platform_service] }
|
|
redirect_uris: { type: array, items: { type: string } }
|
|
client_type: { type: string, enum: [public, confidential] }
|