@nasebanal/cli 0.1.0 → 0.3.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.
@@ -1,10 +1,8 @@
1
1
  openapi: 3.0.3
2
2
  info:
3
3
  title: NASEBANAL Account API
4
- description: >-
5
- Centralized user and billing management API for NASEBANAL applications. Manages user profiles, per-service
6
- subscriptions, Stripe billing, and Personal Access Tokens (PAT).
7
- version: 1.4.0
4
+ description: Centralized user and billing management API for NASEBANAL applications. Manages user profiles, per-service subscriptions, Stripe billing, and Personal Access Tokens (PAT).
5
+ version: 1.5.1
8
6
  contact:
9
7
  name: NASEBANAL
10
8
  url: https://www.nasebanal.com
@@ -24,7 +22,7 @@ paths:
24
22
  description: Returns the health status of the API.
25
23
  security: []
26
24
  responses:
27
- '200':
25
+ "200":
28
26
  description: API is healthy
29
27
  content:
30
28
  application/json:
@@ -44,34 +42,26 @@ paths:
44
42
  summary: Get current user profile
45
43
  description: Returns the authenticated user's profile information including subscription details.
46
44
  responses:
47
- '200':
45
+ "200":
48
46
  description: User profile
49
47
  content:
50
48
  application/json:
51
49
  schema:
52
- $ref: '#/components/schemas/UserResponse'
53
- '401':
54
- $ref: '#/components/responses/Unauthorized'
50
+ $ref: "#/components/schemas/UserResponse"
51
+ "401":
52
+ $ref: "#/components/responses/Unauthorized"
55
53
  delete:
56
54
  tags:
57
55
  - User
58
56
  summary: Delete account
59
- description: >-
60
- Permanently deletes the authenticated user's account and every service's data for it: Recorder records, tags and
61
- media, Target goals, shares on both sides, organization memberships, and API tokens. An active personal
62
- subscription is cancelled at Stripe as part of the same call.
57
+ description: |-
58
+ Permanently deletes the authenticated user's account and every service's data for it: Recorder records, tags and media, Target goals, shares on both sides, organization memberships, and API tokens. An active personal subscription is cancelled at Stripe as part of the same call.
63
59
 
60
+ Irreversible — there is no soft-delete or reactivation. Callers must confirm intent before invoking, and must send the user through logout afterwards: their access token stays cryptographically valid but no longer resolves to an account, so a subsequent authenticated request would provision a brand-new empty user.
64
61
 
65
- Irreversible — there is no soft-delete or reactivation. Callers must confirm intent before invoking, and must
66
- send the user through logout afterwards: their access token stays cryptographically valid but no longer resolves
67
- to an account, so a subsequent authenticated request would provision a brand-new empty user.
68
-
69
-
70
- Refused with `409` while the caller is the only administrator of an organization that still has other members;
71
- the organization must be handed over or deleted first. `502` means nothing was deleted (a downstream service
72
- could not be purged) and the request can safely be retried.
62
+ Refused with `409` while the caller is the only administrator of an organization that still has other members; the organization must be handed over or deleted first. `502` means nothing was deleted (a downstream service could not be purged) and the request can safely be retried.
73
63
  responses:
74
- '200':
64
+ "200":
75
65
  description: Account deleted
76
66
  content:
77
67
  application/json:
@@ -83,7 +73,8 @@ paths:
83
73
  properties:
84
74
  success:
85
75
  type: boolean
86
- enum: [true]
76
+ enum:
77
+ - true
87
78
  data:
88
79
  type: object
89
80
  required:
@@ -92,7 +83,8 @@ paths:
92
83
  properties:
93
84
  deleted:
94
85
  type: boolean
95
- enum: [true]
86
+ enum:
87
+ - true
96
88
  user_id:
97
89
  type: integer
98
90
  organizations_deleted:
@@ -102,30 +94,27 @@ paths:
102
94
  type: integer
103
95
  auth0_identity_deleted:
104
96
  type: boolean
105
- description: >-
106
- Whether the Auth0 identity was removed as well. False when the API has no Management API
107
- credentials configured — the account data is still fully deleted, but signing in again creates
108
- a new empty account.
109
- '401':
110
- $ref: '#/components/responses/Unauthorized'
111
- '403':
97
+ description: Whether the Auth0 identity was removed as well. False when the API has no Management API credentials configured — the account data is still fully deleted, but signing in again creates a new empty account.
98
+ "401":
99
+ $ref: "#/components/responses/Unauthorized"
100
+ "403":
112
101
  description: Service accounts cannot be deleted through this endpoint
113
102
  content:
114
103
  application/json:
115
104
  schema:
116
- $ref: '#/components/schemas/Error'
117
- '409':
105
+ $ref: "#/components/schemas/Error"
106
+ "409":
118
107
  description: The caller is the last administrator of an organization that still has members
119
108
  content:
120
109
  application/json:
121
110
  schema:
122
- $ref: '#/components/schemas/Error'
123
- '502':
111
+ $ref: "#/components/schemas/Error"
112
+ "502":
124
113
  description: A downstream service could not be purged — nothing was deleted
125
114
  content:
126
115
  application/json:
127
116
  schema:
128
- $ref: '#/components/schemas/Error'
117
+ $ref: "#/components/schemas/Error"
129
118
  /api/v1/me/profile:
130
119
  put:
131
120
  tags:
@@ -137,16 +126,16 @@ paths:
137
126
  content:
138
127
  application/json:
139
128
  schema:
140
- $ref: '#/components/schemas/UpdateProfileInput'
129
+ $ref: "#/components/schemas/UpdateProfileInput"
141
130
  responses:
142
- '200':
131
+ "200":
143
132
  description: Profile updated
144
133
  content:
145
134
  application/json:
146
135
  schema:
147
- $ref: '#/components/schemas/UserResponse'
148
- '401':
149
- $ref: '#/components/responses/Unauthorized'
136
+ $ref: "#/components/schemas/UserResponse"
137
+ "401":
138
+ $ref: "#/components/responses/Unauthorized"
150
139
  /api/v1/me/accept-terms:
151
140
  post:
152
141
  tags:
@@ -154,60 +143,28 @@ paths:
154
143
  summary: Accept terms of service
155
144
  description: Records the user's acceptance of the terms of service.
156
145
  responses:
157
- '200':
146
+ "200":
158
147
  description: Terms accepted
159
148
  content:
160
149
  application/json:
161
150
  schema:
162
151
  type: object
152
+ required:
153
+ - success
154
+ - data
163
155
  properties:
156
+ success:
157
+ type: boolean
158
+ enum:
159
+ - true
164
160
  data:
165
161
  type: object
166
162
  properties:
167
163
  tos_accepted_at:
168
164
  type: string
169
165
  format: date-time
170
- '401':
171
- $ref: '#/components/responses/Unauthorized'
172
- /api/v1/me/subscription:
173
- x-internal: true
174
- get:
175
- tags:
176
- - Subscriptions
177
- summary: Get subscription info (legacy)
178
- description: Returns the authenticated user's legacy subscription information.
179
- responses:
180
- '200':
181
- description: Subscription info
182
- content:
183
- application/json:
184
- schema:
185
- type: object
186
- properties:
187
- data:
188
- type: object
189
- properties:
190
- plan:
191
- type: string
192
- enum:
193
- - free
194
- - pro
195
- - family
196
- - enterprise
197
- subscription_id:
198
- type: string
199
- subscription_status:
200
- type: string
201
- enum:
202
- - active
203
- - canceled
204
- - past_due
205
- - trialing
206
- subscription_expires_at:
207
- type: string
208
- format: date-time
209
- '401':
210
- $ref: '#/components/responses/Unauthorized'
166
+ "401":
167
+ $ref: "#/components/responses/Unauthorized"
211
168
  /api/v1/me/subscriptions:
212
169
  get:
213
170
  tags:
@@ -215,19 +172,26 @@ paths:
215
172
  summary: Get all per-service subscriptions
216
173
  description: Returns all per-service subscriptions for the authenticated user.
217
174
  responses:
218
- '200':
175
+ "200":
219
176
  description: List of service subscriptions
220
177
  content:
221
178
  application/json:
222
179
  schema:
223
180
  type: object
181
+ required:
182
+ - success
183
+ - data
224
184
  properties:
185
+ success:
186
+ type: boolean
187
+ enum:
188
+ - true
225
189
  data:
226
190
  type: array
227
191
  items:
228
- $ref: '#/components/schemas/ServiceSubscription'
229
- '401':
230
- $ref: '#/components/responses/Unauthorized'
192
+ $ref: "#/components/schemas/ServiceSubscription"
193
+ "401":
194
+ $ref: "#/components/responses/Unauthorized"
231
195
  /api/v1/me/subscriptions/{serviceId}:
232
196
  get:
233
197
  tags:
@@ -241,114 +205,26 @@ paths:
241
205
  schema:
242
206
  type: string
243
207
  responses:
244
- '200':
208
+ "200":
245
209
  description: Service subscription
246
210
  content:
247
211
  application/json:
248
212
  schema:
249
213
  type: object
214
+ required:
215
+ - success
216
+ - data
250
217
  properties:
218
+ success:
219
+ type: boolean
220
+ enum:
221
+ - true
251
222
  data:
252
- $ref: '#/components/schemas/ServiceSubscription'
253
- '401':
254
- $ref: '#/components/responses/Unauthorized'
255
- '404':
256
- $ref: '#/components/responses/NotFound'
257
- /api/v1/stripe/checkout:
258
- x-internal: true
259
- post:
260
- tags:
261
- - Stripe
262
- summary: Create Stripe checkout session
263
- description: Creates a new Stripe checkout session for subscription purchase.
264
- requestBody:
265
- required: true
266
- content:
267
- application/json:
268
- schema:
269
- type: object
270
- required:
271
- - plan
272
- properties:
273
- plan:
274
- type: string
275
- enum: [pro, family]
276
- description: Target subscription plan.
277
- serviceId:
278
- type: string
279
- description: Service the subscription applies to (defaults to "default").
280
- currency:
281
- type: string
282
- enum: [jpy, usd]
283
- default: jpy
284
- description: >-
285
- Billing currency for the new subscription; selects the matching
286
- per-currency Stripe Price. Defaults to jpy when omitted. Stripe
287
- locks a customer to this currency on first payment, so it only
288
- applies to the initial checkout.
289
- returnUrl:
290
- type: string
291
- description: >-
292
- Locale-aware URL Stripe returns the user to; the result query
293
- string (?upgrade=success&plan=…&serviceId=…) is appended by the API.
294
- responses:
295
- '200':
296
- description: Checkout session created
297
- content:
298
- application/json:
299
- schema:
300
- type: object
301
- properties:
302
- data:
303
- type: object
304
- properties:
305
- url:
306
- type: string
307
- description: Stripe checkout session URL
308
- '401':
309
- $ref: '#/components/responses/Unauthorized'
310
- /api/v1/stripe/change-plan:
311
- x-internal: true
312
- post:
313
- tags:
314
- - Stripe
315
- summary: Change subscription plan
316
- description: Changes the authenticated user's subscription plan.
317
- responses:
318
- '200':
319
- description: Plan changed
320
- content:
321
- application/json:
322
- schema:
323
- type: object
324
- properties:
325
- data:
326
- type: object
327
- '401':
328
- $ref: '#/components/responses/Unauthorized'
329
- /api/v1/stripe/portal:
330
- x-internal: true
331
- post:
332
- tags:
333
- - Stripe
334
- summary: Create customer portal session
335
- description: Creates a Stripe customer portal session for subscription management.
336
- responses:
337
- '200':
338
- description: Portal session created
339
- content:
340
- application/json:
341
- schema:
342
- type: object
343
- properties:
344
- data:
345
- type: object
346
- properties:
347
- url:
348
- type: string
349
- description: Stripe customer portal URL
350
- '401':
351
- $ref: '#/components/responses/Unauthorized'
223
+ $ref: "#/components/schemas/ServiceSubscription"
224
+ "401":
225
+ $ref: "#/components/responses/Unauthorized"
226
+ "404":
227
+ $ref: "#/components/responses/NotFound"
352
228
  /api/v1/me/tokens:
353
229
  get:
354
230
  tags:
@@ -356,24 +232,31 @@ paths:
356
232
  summary: List API tokens
357
233
  description: Returns all Personal Access Tokens for the authenticated user.
358
234
  responses:
359
- '200':
235
+ "200":
360
236
  description: List of API tokens
361
237
  content:
362
238
  application/json:
363
239
  schema:
364
240
  type: object
241
+ required:
242
+ - success
243
+ - data
365
244
  properties:
245
+ success:
246
+ type: boolean
247
+ enum:
248
+ - true
366
249
  data:
367
250
  type: object
368
251
  properties:
369
252
  data:
370
253
  type: array
371
254
  items:
372
- $ref: '#/components/schemas/ApiToken'
255
+ $ref: "#/components/schemas/ApiToken"
373
256
  total:
374
257
  type: integer
375
- '401':
376
- $ref: '#/components/responses/Unauthorized'
258
+ "401":
259
+ $ref: "#/components/responses/Unauthorized"
377
260
  post:
378
261
  tags:
379
262
  - API Tokens
@@ -384,26 +267,33 @@ paths:
384
267
  content:
385
268
  application/json:
386
269
  schema:
387
- $ref: '#/components/schemas/CreateApiTokenInput'
270
+ $ref: "#/components/schemas/CreateApiTokenInput"
388
271
  responses:
389
- '201':
272
+ "201":
390
273
  description: Token created
391
274
  content:
392
275
  application/json:
393
276
  schema:
394
277
  type: object
278
+ required:
279
+ - success
280
+ - data
395
281
  properties:
282
+ success:
283
+ type: boolean
284
+ enum:
285
+ - true
396
286
  data:
397
287
  allOf:
398
- - $ref: '#/components/schemas/ApiToken'
288
+ - $ref: "#/components/schemas/ApiToken"
399
289
  - type: object
400
290
  properties:
401
291
  token:
402
292
  type: string
403
293
  description: The raw token (only returned on creation)
404
294
  example: nbpat_a1b2c3d4e5f6g7h8i9j0...
405
- '401':
406
- $ref: '#/components/responses/Unauthorized'
295
+ "401":
296
+ $ref: "#/components/responses/Unauthorized"
407
297
  /api/v1/me/tokens/{id}:
408
298
  delete:
409
299
  tags:
@@ -417,23 +307,212 @@ paths:
417
307
  schema:
418
308
  type: integer
419
309
  responses:
420
- '200':
310
+ "200":
421
311
  description: Token deleted
422
312
  content:
423
313
  application/json:
424
314
  schema:
425
315
  type: object
316
+ required:
317
+ - success
318
+ - data
426
319
  properties:
320
+ success:
321
+ type: boolean
322
+ enum:
323
+ - true
427
324
  data:
428
325
  type: object
429
326
  properties:
430
327
  success:
431
328
  type: boolean
432
329
  example: true
433
- '401':
434
- $ref: '#/components/responses/Unauthorized'
435
- '404':
436
- $ref: '#/components/responses/NotFound'
330
+ "401":
331
+ $ref: "#/components/responses/Unauthorized"
332
+ "404":
333
+ $ref: "#/components/responses/NotFound"
334
+ /api/v1/me/notifications:
335
+ get:
336
+ tags:
337
+ - Notifications
338
+ summary: List notifications
339
+ description: Returns the caller's in-app notifications, newest first, with the total unread count. Read rows are deleted 30 days after they were read and unread rows 90 days after their last update.
340
+ parameters:
341
+ - name: limit
342
+ in: query
343
+ required: false
344
+ description: Maximum rows to return.
345
+ schema:
346
+ type: integer
347
+ minimum: 1
348
+ maximum: 100
349
+ default: 30
350
+ - name: unread_only
351
+ in: query
352
+ required: false
353
+ description: Return only unread rows.
354
+ schema:
355
+ type: boolean
356
+ default: false
357
+ responses:
358
+ "200":
359
+ description: Notifications and the unread count
360
+ content:
361
+ application/json:
362
+ schema:
363
+ type: object
364
+ required:
365
+ - success
366
+ - data
367
+ properties:
368
+ success:
369
+ type: boolean
370
+ enum:
371
+ - true
372
+ data:
373
+ $ref: "#/components/schemas/NotificationInbox"
374
+ "401":
375
+ $ref: "#/components/responses/Unauthorized"
376
+ /api/v1/me/notifications/unread-count:
377
+ get:
378
+ tags:
379
+ - Notifications
380
+ summary: Unread notification count
381
+ description: Returns only the number of unread notifications. Cheap enough to poll for a badge; use the list endpoint to read the rows.
382
+ responses:
383
+ "200":
384
+ description: Unread count
385
+ content:
386
+ application/json:
387
+ schema:
388
+ type: object
389
+ required:
390
+ - success
391
+ - data
392
+ properties:
393
+ success:
394
+ type: boolean
395
+ enum:
396
+ - true
397
+ data:
398
+ type: object
399
+ properties:
400
+ unread_count:
401
+ type: integer
402
+ minimum: 0
403
+ example: 3
404
+ "401":
405
+ $ref: "#/components/responses/Unauthorized"
406
+ /api/v1/me/notifications/read:
407
+ post:
408
+ tags:
409
+ - Notifications
410
+ summary: Mark notifications as read
411
+ description: "Marks the given rows (`ids`, at most 100) or every unread row (`all: true`) as read. Ids that do not exist or belong to someone else are ignored."
412
+ requestBody:
413
+ required: true
414
+ content:
415
+ application/json:
416
+ schema:
417
+ $ref: "#/components/schemas/MarkNotificationsReadInput"
418
+ responses:
419
+ "200":
420
+ description: Marked as read
421
+ content:
422
+ application/json:
423
+ schema:
424
+ type: object
425
+ required:
426
+ - success
427
+ - data
428
+ properties:
429
+ success:
430
+ type: boolean
431
+ enum:
432
+ - true
433
+ data:
434
+ type: object
435
+ properties:
436
+ updated:
437
+ type: boolean
438
+ example: true
439
+ "401":
440
+ $ref: "#/components/responses/Unauthorized"
441
+ /api/v1/me/device-tokens:
442
+ post:
443
+ tags:
444
+ - Notifications
445
+ summary: Register a device for push
446
+ description: Sends this device's Expo push token to the signed-in account. Registering a token that belongs to another account moves it to the caller, so a shared phone follows whoever is signed in. At most a handful of devices are kept per user (the newest).
447
+ requestBody:
448
+ required: true
449
+ content:
450
+ application/json:
451
+ schema:
452
+ $ref: "#/components/schemas/RegisterDeviceTokenInput"
453
+ responses:
454
+ "200":
455
+ description: Registered
456
+ content:
457
+ application/json:
458
+ schema:
459
+ type: object
460
+ required:
461
+ - success
462
+ - data
463
+ properties:
464
+ success:
465
+ type: boolean
466
+ enum:
467
+ - true
468
+ data:
469
+ type: object
470
+ properties:
471
+ registered:
472
+ type: boolean
473
+ example: true
474
+ "401":
475
+ $ref: "#/components/responses/Unauthorized"
476
+ delete:
477
+ tags:
478
+ - Notifications
479
+ summary: Unregister a device
480
+ description: "Detaches a push token from the caller (on sign-out). Scoped to the caller: another account's token is left alone."
481
+ requestBody:
482
+ required: true
483
+ content:
484
+ application/json:
485
+ schema:
486
+ type: object
487
+ required:
488
+ - token
489
+ properties:
490
+ token:
491
+ type: string
492
+ example: ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]
493
+ responses:
494
+ "200":
495
+ description: Unregistered
496
+ content:
497
+ application/json:
498
+ schema:
499
+ type: object
500
+ required:
501
+ - success
502
+ - data
503
+ properties:
504
+ success:
505
+ type: boolean
506
+ enum:
507
+ - true
508
+ data:
509
+ type: object
510
+ properties:
511
+ unregistered:
512
+ type: boolean
513
+ example: true
514
+ "401":
515
+ $ref: "#/components/responses/Unauthorized"
437
516
  /api/v1/organizations/{orgId}/service-accounts:
438
517
  get:
439
518
  tags:
@@ -447,35 +526,40 @@ paths:
447
526
  schema:
448
527
  type: integer
449
528
  responses:
450
- '200':
529
+ "200":
451
530
  description: List of service accounts
452
531
  content:
453
532
  application/json:
454
533
  schema:
455
534
  type: object
535
+ required:
536
+ - success
537
+ - data
456
538
  properties:
539
+ success:
540
+ type: boolean
541
+ enum:
542
+ - true
457
543
  data:
458
544
  type: object
459
545
  properties:
460
546
  data:
461
547
  type: array
462
548
  items:
463
- $ref: '#/components/schemas/ServiceAccount'
549
+ $ref: "#/components/schemas/ServiceAccount"
464
550
  total:
465
551
  type: integer
466
- '401':
467
- $ref: '#/components/responses/Unauthorized'
468
- '403':
469
- $ref: '#/components/responses/Forbidden'
470
- '404':
471
- $ref: '#/components/responses/NotFound'
552
+ "401":
553
+ $ref: "#/components/responses/Unauthorized"
554
+ "403":
555
+ $ref: "#/components/responses/Forbidden"
556
+ "404":
557
+ $ref: "#/components/responses/NotFound"
472
558
  post:
473
559
  tags:
474
560
  - Service Accounts
475
561
  summary: Create a service account
476
- description: >-
477
- Creates a new service account in the organization. Requires the caller to be an Org Admin AND the organization
478
- to hold an active Enterprise subscription.
562
+ description: Creates a new service account in the organization. Requires the caller to be an Org Admin AND the organization to hold an active Enterprise subscription.
479
563
  parameters:
480
564
  - name: orgId
481
565
  in: path
@@ -487,21 +571,28 @@ paths:
487
571
  content:
488
572
  application/json:
489
573
  schema:
490
- $ref: '#/components/schemas/CreateServiceAccountInput'
574
+ $ref: "#/components/schemas/CreateServiceAccountInput"
491
575
  responses:
492
- '201':
576
+ "201":
493
577
  description: Service account created
494
578
  content:
495
579
  application/json:
496
580
  schema:
497
581
  type: object
582
+ required:
583
+ - success
584
+ - data
498
585
  properties:
586
+ success:
587
+ type: boolean
588
+ enum:
589
+ - true
499
590
  data:
500
- $ref: '#/components/schemas/ServiceAccount'
501
- '401':
502
- $ref: '#/components/responses/Unauthorized'
503
- '403':
504
- $ref: '#/components/responses/Forbidden'
591
+ $ref: "#/components/schemas/ServiceAccount"
592
+ "401":
593
+ $ref: "#/components/responses/Unauthorized"
594
+ "403":
595
+ $ref: "#/components/responses/Forbidden"
505
596
  /api/v1/organizations/{orgId}/service-accounts/{saId}:
506
597
  put:
507
598
  tags:
@@ -523,30 +614,35 @@ paths:
523
614
  content:
524
615
  application/json:
525
616
  schema:
526
- $ref: '#/components/schemas/CreateServiceAccountInput'
617
+ $ref: "#/components/schemas/CreateServiceAccountInput"
527
618
  responses:
528
- '200':
619
+ "200":
529
620
  description: Service account updated
530
621
  content:
531
622
  application/json:
532
623
  schema:
533
624
  type: object
625
+ required:
626
+ - success
627
+ - data
534
628
  properties:
629
+ success:
630
+ type: boolean
631
+ enum:
632
+ - true
535
633
  data:
536
- $ref: '#/components/schemas/ServiceAccount'
537
- '401':
538
- $ref: '#/components/responses/Unauthorized'
539
- '403':
540
- $ref: '#/components/responses/Forbidden'
541
- '404':
542
- $ref: '#/components/responses/NotFound'
634
+ $ref: "#/components/schemas/ServiceAccount"
635
+ "401":
636
+ $ref: "#/components/responses/Unauthorized"
637
+ "403":
638
+ $ref: "#/components/responses/Forbidden"
639
+ "404":
640
+ $ref: "#/components/responses/NotFound"
543
641
  delete:
544
642
  tags:
545
643
  - Service Accounts
546
644
  summary: Delete a service account
547
- description: >-
548
- Deletes the service account and cascades to all of its API tokens. Returns the cascade count for audit
549
- reference.
645
+ description: Deletes the service account and cascades to all of its API tokens. Returns the cascade count for audit reference.
550
646
  parameters:
551
647
  - name: orgId
552
648
  in: path
@@ -559,13 +655,20 @@ paths:
559
655
  schema:
560
656
  type: integer
561
657
  responses:
562
- '200':
658
+ "200":
563
659
  description: Service account deleted
564
660
  content:
565
661
  application/json:
566
662
  schema:
567
663
  type: object
664
+ required:
665
+ - success
666
+ - data
568
667
  properties:
668
+ success:
669
+ type: boolean
670
+ enum:
671
+ - true
569
672
  data:
570
673
  type: object
571
674
  properties:
@@ -573,12 +676,12 @@ paths:
573
676
  type: boolean
574
677
  cascade_token_count:
575
678
  type: integer
576
- '401':
577
- $ref: '#/components/responses/Unauthorized'
578
- '403':
579
- $ref: '#/components/responses/Forbidden'
580
- '404':
581
- $ref: '#/components/responses/NotFound'
679
+ "401":
680
+ $ref: "#/components/responses/Unauthorized"
681
+ "403":
682
+ $ref: "#/components/responses/Forbidden"
683
+ "404":
684
+ $ref: "#/components/responses/NotFound"
582
685
  /api/v1/organizations/{orgId}/service-accounts/{saId}/tokens:
583
686
  get:
584
687
  tags:
@@ -596,35 +699,40 @@ paths:
596
699
  schema:
597
700
  type: integer
598
701
  responses:
599
- '200':
702
+ "200":
600
703
  description: List of tokens
601
704
  content:
602
705
  application/json:
603
706
  schema:
604
707
  type: object
708
+ required:
709
+ - success
710
+ - data
605
711
  properties:
712
+ success:
713
+ type: boolean
714
+ enum:
715
+ - true
606
716
  data:
607
717
  type: object
608
718
  properties:
609
719
  data:
610
720
  type: array
611
721
  items:
612
- $ref: '#/components/schemas/ApiToken'
722
+ $ref: "#/components/schemas/ApiToken"
613
723
  total:
614
724
  type: integer
615
- '401':
616
- $ref: '#/components/responses/Unauthorized'
617
- '403':
618
- $ref: '#/components/responses/Forbidden'
619
- '404':
620
- $ref: '#/components/responses/NotFound'
725
+ "401":
726
+ $ref: "#/components/responses/Unauthorized"
727
+ "403":
728
+ $ref: "#/components/responses/Forbidden"
729
+ "404":
730
+ $ref: "#/components/responses/NotFound"
621
731
  post:
622
732
  tags:
623
733
  - Service Accounts
624
734
  summary: Issue a new token for a service account
625
- description: >-
626
- Creates a new API token under the service account. The raw `nbpat_...` token is returned exactly once; it is not
627
- stored in plaintext and cannot be retrieved later.
735
+ description: Creates a new API token under the service account. The raw `nbpat_...` token is returned exactly once; it is not stored in plaintext and cannot be retrieved later.
628
736
  parameters:
629
737
  - name: orgId
630
738
  in: path
@@ -641,30 +749,37 @@ paths:
641
749
  content:
642
750
  application/json:
643
751
  schema:
644
- $ref: '#/components/schemas/CreateApiTokenInput'
752
+ $ref: "#/components/schemas/CreateApiTokenInput"
645
753
  responses:
646
- '201':
754
+ "201":
647
755
  description: Token issued
648
756
  content:
649
757
  application/json:
650
758
  schema:
651
759
  type: object
760
+ required:
761
+ - success
762
+ - data
652
763
  properties:
764
+ success:
765
+ type: boolean
766
+ enum:
767
+ - true
653
768
  data:
654
769
  allOf:
655
- - $ref: '#/components/schemas/ApiToken'
770
+ - $ref: "#/components/schemas/ApiToken"
656
771
  - type: object
657
772
  properties:
658
773
  token:
659
774
  type: string
660
775
  description: The raw token value (returned once on creation)
661
776
  example: nbpat_a1b2c3d4...
662
- '401':
663
- $ref: '#/components/responses/Unauthorized'
664
- '403':
665
- $ref: '#/components/responses/Forbidden'
666
- '404':
667
- $ref: '#/components/responses/NotFound'
777
+ "401":
778
+ $ref: "#/components/responses/Unauthorized"
779
+ "403":
780
+ $ref: "#/components/responses/Forbidden"
781
+ "404":
782
+ $ref: "#/components/responses/NotFound"
668
783
  /api/v1/organizations/{orgId}/service-accounts/{saId}/tokens/{tokenId}:
669
784
  delete:
670
785
  tags:
@@ -687,24 +802,31 @@ paths:
687
802
  schema:
688
803
  type: integer
689
804
  responses:
690
- '200':
805
+ "200":
691
806
  description: Token revoked
692
807
  content:
693
808
  application/json:
694
809
  schema:
695
810
  type: object
811
+ required:
812
+ - success
813
+ - data
696
814
  properties:
815
+ success:
816
+ type: boolean
817
+ enum:
818
+ - true
697
819
  data:
698
820
  type: object
699
821
  properties:
700
822
  success:
701
823
  type: boolean
702
- '401':
703
- $ref: '#/components/responses/Unauthorized'
704
- '403':
705
- $ref: '#/components/responses/Forbidden'
706
- '404':
707
- $ref: '#/components/responses/NotFound'
824
+ "401":
825
+ $ref: "#/components/responses/Unauthorized"
826
+ "403":
827
+ $ref: "#/components/responses/Forbidden"
828
+ "404":
829
+ $ref: "#/components/responses/NotFound"
708
830
  components:
709
831
  securitySchemes:
710
832
  BearerAuth:
@@ -730,9 +852,7 @@ components:
730
852
  - en
731
853
  timezone:
732
854
  type: string
733
- description: >-
734
- IANA time zone name (e.g. `Asia/Tokyo`), or `auto` to follow the
735
- device the client runs on. Defaults to `auto`.
855
+ description: IANA time zone name (e.g. `Asia/Tokyo`), or `auto` to follow the device the client runs on. Defaults to `auto`.
736
856
  example: auto
737
857
  plan:
738
858
  type: string
@@ -757,7 +877,7 @@ components:
757
877
  subscriptions:
758
878
  type: array
759
879
  items:
760
- $ref: '#/components/schemas/ServiceSubscription'
880
+ $ref: "#/components/schemas/ServiceSubscription"
761
881
  tos_accepted_at:
762
882
  type: string
763
883
  format: date-time
@@ -767,9 +887,16 @@ components:
767
887
  format: date-time
768
888
  UserResponse:
769
889
  type: object
890
+ required:
891
+ - success
892
+ - data
770
893
  properties:
894
+ success:
895
+ type: boolean
896
+ enum:
897
+ - true
771
898
  data:
772
- $ref: '#/components/schemas/User'
899
+ $ref: "#/components/schemas/User"
773
900
  UpdateProfileInput:
774
901
  type: object
775
902
  properties:
@@ -858,12 +985,87 @@ components:
858
985
  type: string
859
986
  format: date-time
860
987
  description: Optional expiration date for the token.
988
+ Notification:
989
+ type: object
990
+ description: One inbox row. Repeats of the same event on the same entity collapse into a single unread row (`count` says how many).
991
+ properties:
992
+ id:
993
+ type: integer
994
+ type:
995
+ type: string
996
+ description: Event kind, e.g. `share.invited`, `share.accepted`, `share.rejected`, `share.revoked`, `ownership.transfer_requested`, `target.updated`, `target.deleted`, `recorder.tag_updated`. New kinds may appear; clients should fall back to a generic sentence for one they do not know.
997
+ example: recorder.tag_updated
998
+ service_id:
999
+ type: string
1000
+ description: Which API raised it (`target`, `recorder`, `account`); tells a client which app the reference belongs to.
1001
+ example: recorder
1002
+ ref_id:
1003
+ type: string
1004
+ nullable: true
1005
+ description: "The entity to open: a target id, a tag id or a share id, depending on `type`."
1006
+ params:
1007
+ type: object
1008
+ additionalProperties: true
1009
+ description: "Display data, never rendered into a push: `actor_name`, `owner_name`, `recipient_name`, `target_title`, `tag_name`, and for `recorder.tag_updated` the latest `change` plus up to five `changes` (newest first), each with `action`, `record_id`, `value`, `unit`, `recorded_at`, `comment`, `media_type` (kind only, never a URL) and for goal edits `kind: goal`, `goal_value`, `direction`."
1010
+ count:
1011
+ type: integer
1012
+ minimum: 1
1013
+ read_at:
1014
+ type: string
1015
+ nullable: true
1016
+ description: UTC, `YYYY-MM-DD HH:MM:SS`. Null while unread.
1017
+ created_at:
1018
+ type: string
1019
+ description: UTC, `YYYY-MM-DD HH:MM:SS`.
1020
+ updated_at:
1021
+ type: string
1022
+ description: UTC, `YYYY-MM-DD HH:MM:SS`. Moves forward when a repeat collapses into the row.
1023
+ NotificationInbox:
1024
+ type: object
1025
+ properties:
1026
+ notifications:
1027
+ type: array
1028
+ items:
1029
+ $ref: "#/components/schemas/Notification"
1030
+ unread_count:
1031
+ type: integer
1032
+ minimum: 0
1033
+ description: Total unread rows, not just those in this page.
1034
+ MarkNotificationsReadInput:
1035
+ type: object
1036
+ description: "Send either `all: true` or a non-empty `ids` array."
1037
+ properties:
1038
+ all:
1039
+ type: boolean
1040
+ enum:
1041
+ - true
1042
+ ids:
1043
+ type: array
1044
+ minItems: 1
1045
+ maxItems: 100
1046
+ items:
1047
+ type: integer
1048
+ example:
1049
+ - 12
1050
+ - 13
1051
+ RegisterDeviceTokenInput:
1052
+ type: object
1053
+ required:
1054
+ - token
1055
+ - platform
1056
+ properties:
1057
+ token:
1058
+ type: string
1059
+ description: An Expo push token.
1060
+ example: ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]
1061
+ platform:
1062
+ type: string
1063
+ enum:
1064
+ - ios
1065
+ - android
861
1066
  ServiceAccount:
862
1067
  type: object
863
- description: >-
864
- A non-human users row scoped to a single organization. SAs hold API tokens via the existing api_tokens table
865
- (user_id = SA.id). They never appear in member lists; verifyToken rejects any JWT bearing the synthetic
866
- 'service-account|' sub.
1068
+ description: A non-human users row scoped to a single organization. SAs hold API tokens via the existing api_tokens table (user_id = SA.id). They never appear in member lists; verifyToken rejects any JWT bearing the synthetic 'service-account|' sub.
867
1069
  properties:
868
1070
  id:
869
1071
  type: integer
@@ -908,22 +1110,10 @@ components:
908
1110
  - success
909
1111
  - error
910
1112
  properties:
911
- # The implementation has always answered with the same two-field
912
- # envelope as a success response, `{ success, error }` — see
913
- # errorResponse() in nb-account-api/src/utils/errors.ts. Only the
914
- # success half of the envelope was ever described here, so every error
915
- # response carried an undeclared `success` property. Specmatic reports
916
- # it as R2003 "Unknown property", which is how this was found: the
917
- # provider contract test covered only /health until the scope was
918
- # widened to GET /api/v1/me -> 401.
919
- #
920
- # Pinned with `enum` for the same reason the success envelope pins it
921
- # to [true] — a plain boolean lets a stub answer `success: true`
922
- # alongside an error body, which is a state the implementation cannot
923
- # produce.
924
1113
  success:
925
1114
  type: boolean
926
- enum: [false]
1115
+ enum:
1116
+ - false
927
1117
  error:
928
1118
  type: object
929
1119
  required:
@@ -934,10 +1124,6 @@ components:
934
1124
  type: string
935
1125
  message:
936
1126
  type: string
937
- # Optional, and omitted entirely when absent: AppError carries
938
- # `details?: Record<string, unknown>` and JSON.stringify drops the
939
- # key when it is undefined. Declared so a response that does carry
940
- # it is not reported as another unknown property.
941
1127
  details:
942
1128
  type: object
943
1129
  additionalProperties: true
@@ -947,7 +1133,7 @@ components:
947
1133
  content:
948
1134
  application/json:
949
1135
  schema:
950
- $ref: '#/components/schemas/Error'
1136
+ $ref: "#/components/schemas/Error"
951
1137
  example:
952
1138
  success: false
953
1139
  error:
@@ -958,7 +1144,7 @@ components:
958
1144
  content:
959
1145
  application/json:
960
1146
  schema:
961
- $ref: '#/components/schemas/Error'
1147
+ $ref: "#/components/schemas/Error"
962
1148
  example:
963
1149
  success: false
964
1150
  error:
@@ -969,7 +1155,7 @@ components:
969
1155
  content:
970
1156
  application/json:
971
1157
  schema:
972
- $ref: '#/components/schemas/Error'
1158
+ $ref: "#/components/schemas/Error"
973
1159
  example:
974
1160
  success: false
975
1161
  error:
@@ -982,9 +1168,9 @@ tags:
982
1168
  description: User profile endpoints
983
1169
  - name: Subscriptions
984
1170
  description: Subscription management endpoints
985
- - name: Stripe
986
- description: Stripe billing and payment endpoints
987
1171
  - name: API Tokens
988
1172
  description: Personal Access Token management
989
1173
  - name: Service Accounts
990
1174
  description: Org-scoped service accounts for Enterprise organizations and their API tokens. Org Admin only.
1175
+ - name: Notifications
1176
+ description: In-app notification inbox and mobile push device registration