170 lines
5.6 KiB
YAML
170 lines
5.6 KiB
YAML
# yaml-language-server: $schema=https://json-schema.org/draft/2020-12/schema
|
|
openapi: 3.1.0
|
|
info:
|
|
title: agent-call SaaS Recording Handoff API
|
|
version: 1.0.0
|
|
description: >-
|
|
Internal storage handshake. Business results still return through RabbitMQ.
|
|
servers:
|
|
- url: https://saas.internal
|
|
security:
|
|
- bearerAuth: []
|
|
paths:
|
|
/internal/v1/outbound/recording-uploads:
|
|
post:
|
|
operationId: createRecordingUpload
|
|
parameters:
|
|
- $ref: '#/components/parameters/TenantId'
|
|
- $ref: '#/components/parameters/RequestId'
|
|
- $ref: '#/components/parameters/IdempotencyKey'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: {$ref: '#/components/schemas/UploadRequest'}
|
|
responses:
|
|
'201':
|
|
description: Upload session created or existing session returned
|
|
headers: {Cache-Control: {schema: {const: no-store}}}
|
|
content:
|
|
application/json:
|
|
schema: {$ref: '#/components/schemas/UploadSession'}
|
|
'200':
|
|
description: Existing upload session
|
|
content:
|
|
application/json:
|
|
schema: {$ref: '#/components/schemas/UploadSession'}
|
|
'401': {$ref: '#/components/responses/Unauthorized'}
|
|
'403': {$ref: '#/components/responses/Forbidden'}
|
|
'409': {$ref: '#/components/responses/Conflict'}
|
|
/internal/v1/outbound/recording-uploads/{upload_id}/complete:
|
|
post:
|
|
operationId: completeRecordingUpload
|
|
parameters:
|
|
- $ref: '#/components/parameters/TenantId'
|
|
- $ref: '#/components/parameters/RequestId'
|
|
- $ref: '#/components/parameters/IdempotencyKey'
|
|
- name: upload_id
|
|
in: path
|
|
required: true
|
|
schema: {$ref: '#/components/schemas/Id'}
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: {$ref: '#/components/schemas/CompleteRequest'}
|
|
responses:
|
|
'200':
|
|
description: Object independently verified
|
|
content:
|
|
application/json:
|
|
schema: {$ref: '#/components/schemas/VerifiedUpload'}
|
|
'409': {$ref: '#/components/responses/Conflict'}
|
|
'410': {$ref: '#/components/responses/Expired'}
|
|
'422': {$ref: '#/components/responses/Unprocessable'}
|
|
'401': {$ref: '#/components/responses/Unauthorized'}
|
|
'403': {$ref: '#/components/responses/Forbidden'}
|
|
components:
|
|
securitySchemes:
|
|
bearerAuth: {type: http, scheme: bearer}
|
|
parameters:
|
|
TenantId:
|
|
name: X-Tenant-ID
|
|
in: header
|
|
required: true
|
|
schema: {type: string}
|
|
RequestId:
|
|
name: X-Request-ID
|
|
in: header
|
|
required: true
|
|
schema: {type: string}
|
|
IdempotencyKey:
|
|
name: Idempotency-Key
|
|
in: header
|
|
required: true
|
|
schema: {type: string}
|
|
schemas:
|
|
Id:
|
|
type: string
|
|
minLength: 1
|
|
maxLength: 128
|
|
pattern: '^[^\s/\\]+$'
|
|
UploadRequest:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- recording_id
|
|
- call_id
|
|
- content_type
|
|
- size_bytes
|
|
- checksum_algorithm
|
|
- checksum
|
|
- channels
|
|
- sample_rate_hz
|
|
- duration_ms
|
|
properties:
|
|
recording_id: {$ref: '#/components/schemas/Id'}
|
|
call_id: {$ref: '#/components/schemas/Id'}
|
|
content_type: {type: string, const: audio/wav}
|
|
size_bytes: {type: integer, minimum: 1}
|
|
checksum_algorithm: {type: string, const: SHA-256}
|
|
checksum: {type: string, pattern: '^[0-9a-f]{64}$'}
|
|
channels: {type: integer, const: 1}
|
|
sample_rate_hz: {type: integer, minimum: 8000}
|
|
duration_ms: {type: integer, minimum: 1}
|
|
UploadSession:
|
|
type: object
|
|
required:
|
|
- upload_id
|
|
- recording_id
|
|
- expires_at
|
|
- upload_method
|
|
- upload_url
|
|
- required_headers
|
|
- constraints
|
|
properties:
|
|
upload_id: {$ref: '#/components/schemas/Id'}
|
|
recording_id: {$ref: '#/components/schemas/Id'}
|
|
expires_at: {type: string, format: date-time}
|
|
upload_method: {const: PUT}
|
|
upload_url: {type: string, format: uri}
|
|
required_headers: {type: object}
|
|
constraints: {type: object}
|
|
oss_id: {type: [string, 'null']}
|
|
CompleteRequest:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [recording_id, size_bytes, checksum_algorithm, checksum]
|
|
properties:
|
|
recording_id: {$ref: '#/components/schemas/Id'}
|
|
size_bytes: {type: integer, minimum: 1}
|
|
checksum_algorithm: {const: SHA-256}
|
|
checksum: {type: string, pattern: '^[0-9a-f]{64}$'}
|
|
etag: {type: [string, 'null']}
|
|
VerifiedUpload:
|
|
type: object
|
|
required: [upload_id, recording_id, status, oss_id, verified_at]
|
|
properties:
|
|
upload_id: {$ref: '#/components/schemas/Id'}
|
|
recording_id: {$ref: '#/components/schemas/Id'}
|
|
status: {const: verified}
|
|
oss_id: {type: string}
|
|
verified_at: {type: string, format: date-time}
|
|
Problem:
|
|
type: object
|
|
required: [type, title, status, code, detail, request_id, retryable]
|
|
properties:
|
|
type: {type: string}
|
|
title: {type: string}
|
|
status: {type: integer}
|
|
code: {type: string}
|
|
detail: {type: string}
|
|
request_id: {type: string}
|
|
retryable: {type: boolean}
|
|
responses:
|
|
Unauthorized: {description: Unauthorized}
|
|
Forbidden: {description: Forbidden}
|
|
Conflict: {description: Idempotency conflict}
|
|
Expired: {description: Upload expired}
|
|
Unprocessable: {description: Object failed independent verification}
|