mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 18:41:08 +02:00
docs(memoro/server): add OpenAPI 3.1 spec and update ManaScore to 79
- Add openapi.yaml with all 50+ endpoints, schemas, and auth methods - Update ManaScore: 76→79 (testing 45→55, documentation 78→82) - 210 tests total (main-server 185 + audio-server 25) - API conformity: documentation now true Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c582f164ba
commit
9aedc89ce5
2 changed files with 943 additions and 19 deletions
926
apps/memoro/apps/server/openapi.yaml
Normal file
926
apps/memoro/apps/server/openapi.yaml
Normal file
|
|
@ -0,0 +1,926 @@
|
|||
openapi: 3.1.0
|
||||
info:
|
||||
title: Memoro Server API
|
||||
description: AI-powered voice memo management — memo processing, spaces, credits, meetings, settings.
|
||||
version: 1.0.0
|
||||
contact:
|
||||
name: ManaCore
|
||||
url: https://mana.how
|
||||
|
||||
servers:
|
||||
- url: http://localhost:3015
|
||||
description: Local development
|
||||
- url: https://memoro.mana.how
|
||||
description: Production
|
||||
|
||||
tags:
|
||||
- name: Health
|
||||
description: Health check and public endpoints
|
||||
- name: Memos
|
||||
description: Memo creation, transcription, and AI operations
|
||||
- name: Spaces
|
||||
description: Collaborative workspaces and invitations
|
||||
- name: Invites
|
||||
description: Pending invite management
|
||||
- name: Credits
|
||||
description: Mana credit balance, validation, and consumption
|
||||
- name: Settings
|
||||
description: User profile and app settings
|
||||
- name: Meetings
|
||||
description: Meeting bot and recording management
|
||||
- name: Internal
|
||||
description: Service-to-service callbacks (X-Service-Key auth)
|
||||
- name: Cleanup
|
||||
description: Audio file cleanup (X-Internal-API-Key auth)
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
serviceKey:
|
||||
type: apiKey
|
||||
in: header
|
||||
name: X-Service-Key
|
||||
internalKey:
|
||||
type: apiKey
|
||||
in: header
|
||||
name: X-Internal-API-Key
|
||||
|
||||
schemas:
|
||||
ApiResult:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
error:
|
||||
type: string
|
||||
required: [success]
|
||||
|
||||
PaginationQuery:
|
||||
type: object
|
||||
properties:
|
||||
limit:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 100
|
||||
default: 50
|
||||
offset:
|
||||
type: integer
|
||||
minimum: 0
|
||||
default: 0
|
||||
|
||||
CreateMemoBody:
|
||||
type: object
|
||||
required: [filePath, duration]
|
||||
properties:
|
||||
filePath:
|
||||
type: string
|
||||
minLength: 1
|
||||
duration:
|
||||
type: number
|
||||
minimum: 0
|
||||
spaceId:
|
||||
type: string
|
||||
format: uuid
|
||||
blueprintId:
|
||||
type: string
|
||||
format: uuid
|
||||
memoId:
|
||||
type: string
|
||||
format: uuid
|
||||
recordingStartedAt:
|
||||
type: string
|
||||
mediaType:
|
||||
type: string
|
||||
|
||||
AppendMemoBody:
|
||||
type: object
|
||||
required: [filePath, duration]
|
||||
properties:
|
||||
filePath:
|
||||
type: string
|
||||
minLength: 1
|
||||
duration:
|
||||
type: number
|
||||
minimum: 0
|
||||
recordingIndex:
|
||||
type: integer
|
||||
minimum: 0
|
||||
recordingLanguages:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
enableDiarization:
|
||||
type: boolean
|
||||
|
||||
CombineMemoBody:
|
||||
type: object
|
||||
required: [memoIds]
|
||||
properties:
|
||||
memoIds:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
minItems: 2
|
||||
|
||||
QuestionMemoBody:
|
||||
type: object
|
||||
required: [question]
|
||||
properties:
|
||||
question:
|
||||
type: string
|
||||
minLength: 1
|
||||
|
||||
CreateSpaceBody:
|
||||
type: object
|
||||
required: [name]
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
minLength: 1
|
||||
description:
|
||||
type: string
|
||||
|
||||
LinkMemoBody:
|
||||
type: object
|
||||
required: [memoId]
|
||||
properties:
|
||||
memoId:
|
||||
type: string
|
||||
format: uuid
|
||||
|
||||
InviteBody:
|
||||
type: object
|
||||
required: [email]
|
||||
properties:
|
||||
email:
|
||||
type: string
|
||||
format: email
|
||||
|
||||
InviteActionBody:
|
||||
type: object
|
||||
required: [inviteId]
|
||||
properties:
|
||||
inviteId:
|
||||
type: string
|
||||
format: uuid
|
||||
|
||||
CreateBotBody:
|
||||
type: object
|
||||
required: [meeting_url]
|
||||
properties:
|
||||
meeting_url:
|
||||
type: string
|
||||
pattern: '^https://(teams\.microsoft\.com|meet\.google\.com|[\w-]+\.zoom\.us)/'
|
||||
space_id:
|
||||
type: string
|
||||
format: uuid
|
||||
|
||||
CheckCreditsBody:
|
||||
type: object
|
||||
required: [operation, amount]
|
||||
properties:
|
||||
operation:
|
||||
type: string
|
||||
minLength: 1
|
||||
amount:
|
||||
type: number
|
||||
minimum: 0
|
||||
|
||||
ConsumeCreditsBody:
|
||||
type: object
|
||||
required: [operation, amount, description]
|
||||
properties:
|
||||
operation:
|
||||
type: string
|
||||
minLength: 1
|
||||
amount:
|
||||
type: number
|
||||
minimum: 0
|
||||
description:
|
||||
type: string
|
||||
minLength: 1
|
||||
metadata:
|
||||
type: object
|
||||
|
||||
UpdateProfileBody:
|
||||
type: object
|
||||
properties:
|
||||
display_name:
|
||||
type: string
|
||||
avatar_url:
|
||||
type: string
|
||||
format: uri
|
||||
bio:
|
||||
type: string
|
||||
maxLength: 500
|
||||
|
||||
UpdateDataUsageBody:
|
||||
type: object
|
||||
required: [accepted]
|
||||
properties:
|
||||
accepted:
|
||||
type: boolean
|
||||
|
||||
TranscriptionCompletedBody:
|
||||
type: object
|
||||
required: [memoId, userId, success]
|
||||
properties:
|
||||
memoId:
|
||||
type: string
|
||||
userId:
|
||||
type: string
|
||||
success:
|
||||
type: boolean
|
||||
transcriptionResult:
|
||||
type: object
|
||||
properties:
|
||||
transcript:
|
||||
type: string
|
||||
utterances:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
offset: { type: number }
|
||||
duration: { type: number }
|
||||
text: { type: string }
|
||||
speaker: { type: string }
|
||||
languages:
|
||||
type: array
|
||||
items: { type: string }
|
||||
primary_language:
|
||||
type: string
|
||||
duration:
|
||||
type: number
|
||||
route:
|
||||
type: string
|
||||
error:
|
||||
type: string
|
||||
fallbackStage:
|
||||
type: string
|
||||
|
||||
ManualCleanupBody:
|
||||
type: object
|
||||
properties:
|
||||
userIds:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
|
||||
CreditCosts:
|
||||
type: object
|
||||
properties:
|
||||
TRANSCRIPTION_PER_MINUTE: { type: number, example: 2 }
|
||||
HEADLINE_GENERATION: { type: number, example: 10 }
|
||||
MEMORY_CREATION: { type: number, example: 10 }
|
||||
BLUEPRINT_PROCESSING: { type: number, example: 5 }
|
||||
QUESTION_MEMO: { type: number, example: 5 }
|
||||
MEMO_COMBINE: { type: number, example: 5 }
|
||||
MEETING_RECORDING_PER_MINUTE: { type: number, example: 2 }
|
||||
|
||||
paths:
|
||||
/health:
|
||||
get:
|
||||
tags: [Health]
|
||||
summary: Health check with dependency status
|
||||
responses:
|
||||
'200':
|
||||
description: All systems operational
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
status: { type: string, enum: [ok, degraded] }
|
||||
service: { type: string }
|
||||
runtime: { type: string }
|
||||
timestamp: { type: string, format: date-time }
|
||||
checks:
|
||||
type: object
|
||||
properties:
|
||||
supabase: { type: string, enum: [ok, error] }
|
||||
'503':
|
||||
description: One or more dependencies degraded
|
||||
|
||||
/api/v1/credits/pricing:
|
||||
get:
|
||||
tags: [Credits]
|
||||
summary: Get credit cost constants (public, no auth)
|
||||
responses:
|
||||
'200':
|
||||
description: Cost constants
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
costs:
|
||||
$ref: '#/components/schemas/CreditCosts'
|
||||
|
||||
# ── Memos ────────────────────────────────────────────────────────
|
||||
|
||||
/api/v1/memos:
|
||||
post:
|
||||
tags: [Memos]
|
||||
summary: Create memo from uploaded file
|
||||
security: [{ bearerAuth: [] }]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CreateMemoBody'
|
||||
responses:
|
||||
'201': { description: Memo created, transcription started }
|
||||
'400': { description: Validation error }
|
||||
'402': { description: Insufficient credits }
|
||||
|
||||
/api/v1/memos/{id}/append:
|
||||
post:
|
||||
tags: [Memos]
|
||||
summary: Append transcription to existing memo
|
||||
security: [{ bearerAuth: [] }]
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/AppendMemoBody'
|
||||
responses:
|
||||
'200': { description: Append transcription started }
|
||||
'400': { description: Validation error }
|
||||
'402': { description: Insufficient credits }
|
||||
'404': { description: Memo not found }
|
||||
|
||||
/api/v1/memos/{id}/retry-transcription:
|
||||
post:
|
||||
tags: [Memos]
|
||||
summary: Retry failed transcription
|
||||
security: [{ bearerAuth: [] }]
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
responses:
|
||||
'200': { description: Transcription retry started }
|
||||
'400': { description: No audio file }
|
||||
'404': { description: Memo not found }
|
||||
|
||||
/api/v1/memos/{id}/retry-headline:
|
||||
post:
|
||||
tags: [Memos]
|
||||
summary: Retry headline generation
|
||||
security: [{ bearerAuth: [] }]
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
responses:
|
||||
'200': { description: Headline regenerated }
|
||||
'404': { description: Memo not found }
|
||||
'500': { description: Generation failed }
|
||||
|
||||
/api/v1/memos/combine:
|
||||
post:
|
||||
tags: [Memos]
|
||||
summary: Combine multiple memos with AI
|
||||
security: [{ bearerAuth: [] }]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CombineMemoBody'
|
||||
responses:
|
||||
'200': { description: Memos combined }
|
||||
'400': { description: Validation error }
|
||||
'402': { description: Insufficient credits }
|
||||
'404': { description: One or more memos not found }
|
||||
|
||||
/api/v1/memos/{id}/question:
|
||||
post:
|
||||
tags: [Memos]
|
||||
summary: Ask a question about memo transcript
|
||||
security: [{ bearerAuth: [] }]
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/QuestionMemoBody'
|
||||
responses:
|
||||
'200': { description: Answer generated }
|
||||
'400': { description: Validation error or no transcript }
|
||||
'402': { description: Insufficient credits }
|
||||
'404': { description: Memo not found }
|
||||
|
||||
# ── Spaces ───────────────────────────────────────────────────────
|
||||
|
||||
/api/v1/spaces:
|
||||
get:
|
||||
tags: [Spaces]
|
||||
summary: List user's spaces
|
||||
security: [{ bearerAuth: [] }]
|
||||
parameters:
|
||||
- name: limit
|
||||
in: query
|
||||
schema: { type: integer, default: 50, maximum: 100 }
|
||||
- name: offset
|
||||
in: query
|
||||
schema: { type: integer, default: 0 }
|
||||
responses:
|
||||
'200': { description: List of spaces with pagination }
|
||||
post:
|
||||
tags: [Spaces]
|
||||
summary: Create a space
|
||||
security: [{ bearerAuth: [] }]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CreateSpaceBody'
|
||||
responses:
|
||||
'201': { description: Space created }
|
||||
'400': { description: Validation error }
|
||||
|
||||
/api/v1/spaces/{id}:
|
||||
get:
|
||||
tags: [Spaces]
|
||||
summary: Get space details
|
||||
security: [{ bearerAuth: [] }]
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
responses:
|
||||
'200': { description: Space details }
|
||||
'403': { description: Access denied }
|
||||
'404': { description: Space not found }
|
||||
delete:
|
||||
tags: [Spaces]
|
||||
summary: Delete space (owner only)
|
||||
security: [{ bearerAuth: [] }]
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
responses:
|
||||
'200': { description: Space deleted }
|
||||
'403': { description: Not the owner }
|
||||
'404': { description: Space not found }
|
||||
|
||||
/api/v1/spaces/{id}/leave:
|
||||
post:
|
||||
tags: [Spaces]
|
||||
summary: Leave a space (non-owner)
|
||||
security: [{ bearerAuth: [] }]
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
responses:
|
||||
'200': { description: Left space }
|
||||
'400': { description: Owner cannot leave }
|
||||
'403': { description: Not a member }
|
||||
|
||||
/api/v1/spaces/{id}/memos/link:
|
||||
post:
|
||||
tags: [Spaces]
|
||||
summary: Link memo to space
|
||||
security: [{ bearerAuth: [] }]
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/LinkMemoBody'
|
||||
responses:
|
||||
'200': { description: Memo linked }
|
||||
'403': { description: Not a member }
|
||||
|
||||
/api/v1/spaces/{id}/memos/unlink:
|
||||
post:
|
||||
tags: [Spaces]
|
||||
summary: Unlink memo from space
|
||||
security: [{ bearerAuth: [] }]
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/LinkMemoBody'
|
||||
responses:
|
||||
'200': { description: Memo unlinked }
|
||||
|
||||
/api/v1/spaces/{id}/memos:
|
||||
get:
|
||||
tags: [Spaces]
|
||||
summary: List memos in space
|
||||
security: [{ bearerAuth: [] }]
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
- name: limit
|
||||
in: query
|
||||
schema: { type: integer, default: 50 }
|
||||
- name: offset
|
||||
in: query
|
||||
schema: { type: integer, default: 0 }
|
||||
responses:
|
||||
'200': { description: Paginated memo list }
|
||||
'403': { description: Not a member }
|
||||
|
||||
/api/v1/spaces/{id}/invites:
|
||||
get:
|
||||
tags: [Spaces]
|
||||
summary: List space invites
|
||||
security: [{ bearerAuth: [] }]
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
responses:
|
||||
'200': { description: List of invites }
|
||||
|
||||
/api/v1/spaces/{id}/invite:
|
||||
post:
|
||||
tags: [Spaces]
|
||||
summary: Send invitation to email
|
||||
security: [{ bearerAuth: [] }]
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/InviteBody'
|
||||
responses:
|
||||
'201': { description: Invite created and email sent }
|
||||
'400': { description: Invalid email }
|
||||
'403': { description: Not a member }
|
||||
|
||||
# ── Invites ──────────────────────────────────────────────────────
|
||||
|
||||
/api/v1/invites/pending:
|
||||
get:
|
||||
tags: [Invites]
|
||||
summary: List pending invites for current user
|
||||
security: [{ bearerAuth: [] }]
|
||||
responses:
|
||||
'200': { description: List of pending invites }
|
||||
|
||||
/api/v1/invites/accept:
|
||||
post:
|
||||
tags: [Invites]
|
||||
summary: Accept an invite
|
||||
security: [{ bearerAuth: [] }]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/InviteActionBody'
|
||||
responses:
|
||||
'200': { description: Invite accepted }
|
||||
'404': { description: Invite not found }
|
||||
|
||||
/api/v1/invites/decline:
|
||||
post:
|
||||
tags: [Invites]
|
||||
summary: Decline an invite
|
||||
security: [{ bearerAuth: [] }]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/InviteActionBody'
|
||||
responses:
|
||||
'200': { description: Invite declined }
|
||||
'404': { description: Invite not found }
|
||||
|
||||
# ── Credits ──────────────────────────────────────────────────────
|
||||
|
||||
/api/v1/credits/balance:
|
||||
get:
|
||||
tags: [Credits]
|
||||
summary: Get credit balance
|
||||
security: [{ bearerAuth: [] }]
|
||||
responses:
|
||||
'200':
|
||||
description: Credit balance
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success: { type: boolean }
|
||||
credits: { type: number }
|
||||
totalEarned: { type: number }
|
||||
totalSpent: { type: number }
|
||||
|
||||
/api/v1/credits/check:
|
||||
post:
|
||||
tags: [Credits]
|
||||
summary: Check if user has enough credits
|
||||
security: [{ bearerAuth: [] }]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CheckCreditsBody'
|
||||
responses:
|
||||
'200': { description: Credit validation result }
|
||||
|
||||
/api/v1/credits/consume:
|
||||
post:
|
||||
tags: [Credits]
|
||||
summary: Consume credits
|
||||
security: [{ bearerAuth: [] }]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ConsumeCreditsBody'
|
||||
responses:
|
||||
'200': { description: Credits consumed }
|
||||
|
||||
# ── Settings ─────────────────────────────────────────────────────
|
||||
|
||||
/api/v1/settings:
|
||||
get:
|
||||
tags: [Settings]
|
||||
summary: Get all user settings
|
||||
security: [{ bearerAuth: [] }]
|
||||
responses:
|
||||
'200': { description: User settings }
|
||||
|
||||
/api/v1/settings/memoro:
|
||||
get:
|
||||
tags: [Settings]
|
||||
summary: Get memoro-specific settings
|
||||
security: [{ bearerAuth: [] }]
|
||||
responses:
|
||||
'200': { description: Memoro settings }
|
||||
patch:
|
||||
tags: [Settings]
|
||||
summary: Update memoro settings
|
||||
security: [{ bearerAuth: [] }]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
minProperties: 1
|
||||
responses:
|
||||
'200': { description: Settings updated }
|
||||
'400': { description: Empty body }
|
||||
|
||||
/api/v1/settings/memoro/data-usage:
|
||||
patch:
|
||||
tags: [Settings]
|
||||
summary: Update data usage acceptance
|
||||
security: [{ bearerAuth: [] }]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UpdateDataUsageBody'
|
||||
responses:
|
||||
'200': { description: Data usage updated }
|
||||
|
||||
/api/v1/settings/profile:
|
||||
patch:
|
||||
tags: [Settings]
|
||||
summary: Update user profile
|
||||
security: [{ bearerAuth: [] }]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UpdateProfileBody'
|
||||
responses:
|
||||
'200': { description: Profile updated }
|
||||
'400': { description: Validation error }
|
||||
|
||||
# ── Meetings ─────────────────────────────────────────────────────
|
||||
|
||||
/api/v1/meetings/bots:
|
||||
post:
|
||||
tags: [Meetings]
|
||||
summary: Create meeting bot
|
||||
security: [{ bearerAuth: [] }]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CreateBotBody'
|
||||
responses:
|
||||
'200': { description: Bot created }
|
||||
'400': { description: Invalid meeting URL }
|
||||
'402': { description: Insufficient credits }
|
||||
get:
|
||||
tags: [Meetings]
|
||||
summary: List meeting bots
|
||||
security: [{ bearerAuth: [] }]
|
||||
parameters:
|
||||
- name: space_id
|
||||
in: query
|
||||
schema: { type: string }
|
||||
- name: limit
|
||||
in: query
|
||||
schema: { type: integer, default: 50 }
|
||||
- name: offset
|
||||
in: query
|
||||
schema: { type: integer, default: 0 }
|
||||
responses:
|
||||
'200': { description: List of bots }
|
||||
|
||||
/api/v1/meetings/bots/{id}:
|
||||
get:
|
||||
tags: [Meetings]
|
||||
summary: Get bot by ID
|
||||
security: [{ bearerAuth: [] }]
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
responses:
|
||||
'200': { description: Bot details }
|
||||
'404': { description: Bot not found }
|
||||
|
||||
/api/v1/meetings/bots/{id}/stop:
|
||||
post:
|
||||
tags: [Meetings]
|
||||
summary: Stop a meeting bot
|
||||
security: [{ bearerAuth: [] }]
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
responses:
|
||||
'200': { description: Bot stop signal sent }
|
||||
'404': { description: Bot not found }
|
||||
|
||||
/api/v1/meetings/recordings:
|
||||
get:
|
||||
tags: [Meetings]
|
||||
summary: List recordings
|
||||
security: [{ bearerAuth: [] }]
|
||||
parameters:
|
||||
- name: space_id
|
||||
in: query
|
||||
schema: { type: string }
|
||||
- name: limit
|
||||
in: query
|
||||
schema: { type: integer, default: 50 }
|
||||
- name: offset
|
||||
in: query
|
||||
schema: { type: integer, default: 0 }
|
||||
responses:
|
||||
'200': { description: List of recordings }
|
||||
|
||||
/api/v1/meetings/recordings/{id}:
|
||||
get:
|
||||
tags: [Meetings]
|
||||
summary: Get recording by ID
|
||||
security: [{ bearerAuth: [] }]
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
responses:
|
||||
'200': { description: Recording details }
|
||||
'404': { description: Recording not found }
|
||||
|
||||
/api/v1/meetings/recordings/{id}/to-memo:
|
||||
post:
|
||||
tags: [Meetings]
|
||||
summary: Convert recording to memo
|
||||
security: [{ bearerAuth: [] }]
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string }
|
||||
responses:
|
||||
'200': { description: Memo created from recording }
|
||||
'400': { description: No audio/video file }
|
||||
'404': { description: Recording not found }
|
||||
|
||||
# ── Internal ─────────────────────────────────────────────────────
|
||||
|
||||
/api/v1/internal/transcription-completed:
|
||||
post:
|
||||
tags: [Internal]
|
||||
summary: Transcription completion callback
|
||||
security: [{ serviceKey: [] }]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TranscriptionCompletedBody'
|
||||
responses:
|
||||
'200': { description: Callback processed }
|
||||
|
||||
/api/v1/internal/batch-metadata:
|
||||
post:
|
||||
tags: [Internal]
|
||||
summary: Update batch job metadata
|
||||
security: [{ serviceKey: [] }]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [memoId, jobId]
|
||||
properties:
|
||||
memoId: { type: string }
|
||||
jobId: { type: string }
|
||||
responses:
|
||||
'200': { description: Metadata updated }
|
||||
'404': { description: Memo not found }
|
||||
|
||||
# ── Cleanup ──────────────────────────────────────────────────────
|
||||
|
||||
/api/v1/cleanup/run:
|
||||
post:
|
||||
tags: [Cleanup]
|
||||
summary: Trigger async audio cleanup
|
||||
security: [{ internalKey: [] }]
|
||||
responses:
|
||||
'200': { description: Cleanup started }
|
||||
|
||||
/api/v1/cleanup/manual:
|
||||
post:
|
||||
tags: [Cleanup]
|
||||
summary: Manual cleanup with optional user IDs
|
||||
security: [{ internalKey: [] }]
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ManualCleanupBody'
|
||||
responses:
|
||||
'200': { description: Cleanup result }
|
||||
|
||||
# ── Webhooks ─────────────────────────────────────────────────────
|
||||
|
||||
/meetings/webhooks/bot-events:
|
||||
post:
|
||||
tags: [Meetings]
|
||||
summary: Meeting bot webhook (HMAC-verified)
|
||||
description: Receives recording.completed and recording.failed events from meeting bot service.
|
||||
responses:
|
||||
'200': { description: Event processed }
|
||||
'400': { description: Invalid JSON }
|
||||
'401': { description: Invalid HMAC signature }
|
||||
Loading…
Add table
Add a link
Reference in a new issue