@giveitsmaller/contracts 0.3.0 → 0.5.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.
- package/asyncapi/events.yaml +455 -41
- package/availability/availability.json +586 -91
- package/dist/asyncapi/OperationType.d.ts +5 -1
- package/dist/asyncapi/OperationType.js +4 -0
- package/dist/openapi/models/AudioWatermarkDecodeRequest.d.ts +1 -1
- package/dist/openapi/models/AudioWatermarkDecodeRequest.js +1 -1
- package/dist/openapi/models/AudioWatermarkDecodeResponse.d.ts +1 -1
- package/dist/openapi/models/AudioWatermarkDecodeResponse.js +1 -1
- package/dist/openapi/models/AuthErrorResponse.d.ts +20 -1
- package/dist/openapi/models/AuthErrorResponse.js +1 -1
- package/dist/openapi/models/AuthErrorType.d.ts +1 -1
- package/dist/openapi/models/AuthErrorType.js +1 -1
- package/dist/openapi/models/AvailabilityValue.d.ts +1 -1
- package/dist/openapi/models/AvailabilityValue.js +1 -1
- package/dist/openapi/models/BalanceExhaustedResponse.d.ts +20 -1
- package/dist/openapi/models/BalanceExhaustedResponse.js +1 -1
- package/dist/openapi/models/BalanceExhaustedResponseAllOfLinks.d.ts +1 -1
- package/dist/openapi/models/BalanceExhaustedResponseAllOfLinks.js +1 -1
- package/dist/openapi/models/CallbackEventType.d.ts +1 -1
- package/dist/openapi/models/CallbackEventType.js +1 -1
- package/dist/openapi/models/ConnectionSource.d.ts +1 -1
- package/dist/openapi/models/ConnectionSource.js +1 -1
- package/dist/openapi/models/ContactRequest.d.ts +1 -1
- package/dist/openapi/models/ContactRequest.js +1 -1
- package/dist/openapi/models/ContactSubject.d.ts +1 -1
- package/dist/openapi/models/ContactSubject.js +1 -1
- package/dist/openapi/models/ContactValidationErrorResponse.d.ts +1 -1
- package/dist/openapi/models/ContactValidationErrorResponse.js +1 -1
- package/dist/openapi/models/CreateExternalImport403Response.d.ts +1 -1
- package/dist/openapi/models/CreateExternalImport403Response.js +1 -1
- package/dist/openapi/models/CreateExternalImport422Response.d.ts +23 -0
- package/dist/openapi/models/CreateExternalImport422Response.js +51 -0
- package/dist/openapi/models/CreateWorkflow422Response.d.ts +4 -2
- package/dist/openapi/models/CreateWorkflow422Response.js +15 -1
- package/dist/openapi/models/CreditTransaction.d.ts +1 -1
- package/dist/openapi/models/CreditTransaction.js +1 -1
- package/dist/openapi/models/CreditTransactionSourceBucket.d.ts +1 -1
- package/dist/openapi/models/CreditTransactionSourceBucket.js +1 -1
- package/dist/openapi/models/CreditsBalanceResponse.d.ts +1 -1
- package/dist/openapi/models/CreditsBalanceResponse.js +1 -1
- package/dist/openapi/models/CreditsBalanceSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/CreditsBalanceSuccessEnvelope.js +1 -1
- package/dist/openapi/models/CreditsUsageResponse.d.ts +1 -1
- package/dist/openapi/models/CreditsUsageResponse.js +1 -1
- package/dist/openapi/models/CreditsUsageSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/CreditsUsageSuccessEnvelope.js +1 -1
- package/dist/openapi/models/Delivery.d.ts +1 -1
- package/dist/openapi/models/Delivery.js +1 -1
- package/dist/openapi/models/DeliveryOutputRef.d.ts +1 -1
- package/dist/openapi/models/DeliveryOutputRef.js +1 -1
- package/dist/openapi/models/DeliveryPlan.d.ts +1 -1
- package/dist/openapi/models/DeliveryPlan.js +1 -1
- package/dist/openapi/models/DeliveryPlanOutput.d.ts +1 -1
- package/dist/openapi/models/DeliveryPlanOutput.js +1 -1
- package/dist/openapi/models/DeliveryPlanReason.d.ts +1 -1
- package/dist/openapi/models/DeliveryPlanReason.js +1 -1
- package/dist/openapi/models/DeliverySelection.d.ts +1 -1
- package/dist/openapi/models/DeliverySelection.js +1 -1
- package/dist/openapi/models/ErrorEnvelope.d.ts +20 -1
- package/dist/openapi/models/ErrorEnvelope.js +1 -1
- package/dist/openapi/models/EstimateQuality.d.ts +1 -1
- package/dist/openapi/models/EstimateQuality.js +1 -1
- package/dist/openapi/models/EstimateRange.d.ts +1 -1
- package/dist/openapi/models/EstimateRange.js +1 -1
- package/dist/openapi/models/ExternalDestination.d.ts +1 -1
- package/dist/openapi/models/ExternalDestination.js +1 -1
- package/dist/openapi/models/ExternalImportCreatedResponse.d.ts +1 -1
- package/dist/openapi/models/ExternalImportCreatedResponse.js +1 -1
- package/dist/openapi/models/ExternalImportCreatedSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/ExternalImportCreatedSuccessEnvelope.js +1 -1
- package/dist/openapi/models/ExternalImportRequest.d.ts +1 -1
- package/dist/openapi/models/ExternalImportRequest.js +1 -1
- package/dist/openapi/models/ExternalImportToken.d.ts +1 -1
- package/dist/openapi/models/ExternalImportToken.js +1 -1
- package/dist/openapi/models/ExternalSource.d.ts +1 -1
- package/dist/openapi/models/ExternalSource.js +1 -1
- package/dist/openapi/models/FeatureNotAvailableResponse.d.ts +26 -3
- package/dist/openapi/models/FeatureNotAvailableResponse.js +1 -1
- package/dist/openapi/models/FeatureTierRestrictedResponse.d.ts +20 -1
- package/dist/openapi/models/FeatureTierRestrictedResponse.js +1 -1
- package/dist/openapi/models/FeatureViolation.d.ts +1 -1
- package/dist/openapi/models/FeatureViolation.js +1 -1
- package/dist/openapi/models/JobDefinition.d.ts +17 -6
- package/dist/openapi/models/JobDefinition.js +1 -1
- package/dist/openapi/models/JobDownload.d.ts +1 -1
- package/dist/openapi/models/JobDownload.js +1 -1
- package/dist/openapi/models/JobInputV2.d.ts +16 -1
- package/dist/openapi/models/JobInputV2.js +1 -1
- package/dist/openapi/models/JobOutputSource.d.ts +1 -1
- package/dist/openapi/models/JobOutputSource.js +1 -1
- package/dist/openapi/models/JobResponse.d.ts +1 -1
- package/dist/openapi/models/JobResponse.js +1 -1
- package/dist/openapi/models/JobStatus.d.ts +1 -1
- package/dist/openapi/models/JobStatus.js +1 -1
- package/dist/openapi/models/JobType.d.ts +1 -1
- package/dist/openapi/models/JobType.js +1 -1
- package/dist/openapi/models/LivenessResponse.d.ts +1 -1
- package/dist/openapi/models/LivenessResponse.js +1 -1
- package/dist/openapi/models/LoginUser200Response.d.ts +1 -1
- package/dist/openapi/models/LoginUser200Response.js +1 -1
- package/dist/openapi/models/LoginUser200ResponseData.d.ts +1 -1
- package/dist/openapi/models/LoginUser200ResponseData.js +1 -1
- package/dist/openapi/models/LoginUser200ResponseDataUser.d.ts +1 -1
- package/dist/openapi/models/LoginUser200ResponseDataUser.js +1 -1
- package/dist/openapi/models/LoginUserRequest.d.ts +1 -1
- package/dist/openapi/models/LoginUserRequest.js +1 -1
- package/dist/openapi/models/LogoutUser200Response.d.ts +1 -1
- package/dist/openapi/models/LogoutUser200Response.js +1 -1
- package/dist/openapi/models/MetadataResponse.d.ts +1 -1
- package/dist/openapi/models/MetadataResponse.js +1 -1
- package/dist/openapi/models/MetadataResponseDimensions.d.ts +1 -1
- package/dist/openapi/models/MetadataResponseDimensions.js +1 -1
- package/dist/openapi/models/MetadataResponseExif.d.ts +1 -1
- package/dist/openapi/models/MetadataResponseExif.js +1 -1
- package/dist/openapi/models/MetadataResponseExifGps.d.ts +1 -1
- package/dist/openapi/models/MetadataResponseExifGps.js +1 -1
- package/dist/openapi/models/MetadataSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/MetadataSuccessEnvelope.js +1 -1
- package/dist/openapi/models/MimeGroupSchema.d.ts +1 -1
- package/dist/openapi/models/MimeGroupSchema.js +1 -1
- package/dist/openapi/models/MultipartCompleteRequest.d.ts +1 -1
- package/dist/openapi/models/MultipartCompleteRequest.js +1 -1
- package/dist/openapi/models/MultipartCompleteRequestPartsInner.d.ts +1 -1
- package/dist/openapi/models/MultipartCompleteRequestPartsInner.js +1 -1
- package/dist/openapi/models/MultipartCompleteResponse.d.ts +1 -1
- package/dist/openapi/models/MultipartCompleteResponse.js +1 -1
- package/dist/openapi/models/MultipartCompleteSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/MultipartCompleteSuccessEnvelope.js +1 -1
- package/dist/openapi/models/MultipartInitiateRequestMetadataHint.d.ts +1 -1
- package/dist/openapi/models/MultipartInitiateRequestMetadataHint.js +1 -1
- package/dist/openapi/models/MultipartInitiateResponse.d.ts +20 -4
- package/dist/openapi/models/MultipartInitiateResponse.js +1 -1
- package/dist/openapi/models/MultipartInitiateSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/MultipartInitiateSuccessEnvelope.js +1 -1
- package/dist/openapi/models/MultipartKeepaliveResponse.d.ts +43 -0
- package/dist/openapi/models/MultipartKeepaliveResponse.js +47 -0
- package/dist/openapi/models/MultipartKeepaliveSuccessEnvelope.d.ts +46 -0
- package/dist/openapi/models/MultipartKeepaliveSuccessEnvelope.js +54 -0
- package/dist/openapi/models/MultipartPartListing.d.ts +59 -0
- package/dist/openapi/models/MultipartPartListing.js +55 -0
- package/dist/openapi/models/MultipartPresignRequest.d.ts +41 -0
- package/dist/openapi/models/MultipartPresignRequest.js +43 -0
- package/dist/openapi/models/MultipartPresignResponse.d.ts +46 -0
- package/dist/openapi/models/MultipartPresignResponse.js +48 -0
- package/dist/openapi/models/MultipartPresignSuccessEnvelope.d.ts +46 -0
- package/dist/openapi/models/MultipartPresignSuccessEnvelope.js +54 -0
- package/dist/openapi/models/MultipartStatusResponse.d.ts +103 -0
- package/dist/openapi/models/MultipartStatusResponse.js +76 -0
- package/dist/openapi/models/MultipartStatusSuccessEnvelope.d.ts +46 -0
- package/dist/openapi/models/MultipartStatusSuccessEnvelope.js +54 -0
- package/dist/openapi/models/OperationDefinition.d.ts +1 -1
- package/dist/openapi/models/OperationDefinition.js +1 -1
- package/dist/openapi/models/OperationDownload.d.ts +29 -1
- package/dist/openapi/models/OperationDownload.js +5 -1
- package/dist/openapi/models/OperationInputModel.d.ts +4 -3
- package/dist/openapi/models/OperationInputModel.js +4 -3
- package/dist/openapi/models/OperationResponse.d.ts +20 -1
- package/dist/openapi/models/OperationResponse.js +5 -1
- package/dist/openapi/models/OperationResult.d.ts +1 -1
- package/dist/openapi/models/OperationResult.js +1 -1
- package/dist/openapi/models/OperationResultMetrics.d.ts +1 -1
- package/dist/openapi/models/OperationResultMetrics.js +1 -1
- package/dist/openapi/models/OperationSchemaDefinition.d.ts +23 -2
- package/dist/openapi/models/OperationSchemaDefinition.js +4 -1
- package/dist/openapi/models/OperationStatus.d.ts +1 -1
- package/dist/openapi/models/OperationStatus.js +1 -1
- package/dist/openapi/models/OperationType.d.ts +10 -2
- package/dist/openapi/models/OperationType.js +11 -3
- package/dist/openapi/models/OperationsSchemaResponse.d.ts +1 -1
- package/dist/openapi/models/OperationsSchemaResponse.js +1 -1
- package/dist/openapi/models/OptionSchema.d.ts +1 -1
- package/dist/openapi/models/OptionSchema.js +1 -1
- package/dist/openapi/models/PerRoleCardinalityEntry.d.ts +47 -0
- package/dist/openapi/models/PerRoleCardinalityEntry.js +47 -0
- package/dist/openapi/models/PerValueAvailabilityEntry.d.ts +1 -1
- package/dist/openapi/models/PerValueAvailabilityEntry.js +1 -1
- package/dist/openapi/models/PresignedUrlPart.d.ts +1 -1
- package/dist/openapi/models/PresignedUrlPart.js +1 -1
- package/dist/openapi/models/ProbePendingResponse.d.ts +171 -0
- package/dist/openapi/models/ProbePendingResponse.js +75 -0
- package/dist/openapi/models/ProcessingClass.d.ts +1 -1
- package/dist/openapi/models/ProcessingClass.js +1 -1
- package/dist/openapi/models/ProcessingClassBandViolation.d.ts +149 -0
- package/dist/openapi/models/ProcessingClassBandViolation.js +81 -0
- package/dist/openapi/models/ProcessingClassExceedsBandResponse.d.ts +174 -0
- package/dist/openapi/models/ProcessingClassExceedsBandResponse.js +76 -0
- package/dist/openapi/models/ProcessingClassHint.d.ts +1 -1
- package/dist/openapi/models/ProcessingClassHint.js +1 -1
- package/dist/openapi/models/ProcessingClassReason.d.ts +1 -1
- package/dist/openapi/models/ProcessingClassReason.js +1 -1
- package/dist/openapi/models/ProcessingClassRejectReason.d.ts +53 -0
- package/dist/openapi/models/ProcessingClassRejectReason.js +71 -0
- package/dist/openapi/models/ProcessingPlan.d.ts +1 -1
- package/dist/openapi/models/ProcessingPlan.js +1 -1
- package/dist/openapi/models/ProcessingPlanJob.d.ts +1 -1
- package/dist/openapi/models/ProcessingPlanJob.js +1 -1
- package/dist/openapi/models/ReadinessResponse.d.ts +1 -1
- package/dist/openapi/models/ReadinessResponse.js +1 -1
- package/dist/openapi/models/ResponseEnvelope.d.ts +1 -1
- package/dist/openapi/models/ResponseEnvelope.js +1 -1
- package/dist/openapi/models/RetryResponse.d.ts +1 -1
- package/dist/openapi/models/RetryResponse.js +1 -1
- package/dist/openapi/models/RetrySuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/RetrySuccessEnvelope.js +1 -1
- package/dist/openapi/models/SseEventType.d.ts +1 -1
- package/dist/openapi/models/SseEventType.js +1 -1
- package/dist/openapi/models/SseJobCompletedData.d.ts +1 -1
- package/dist/openapi/models/SseJobCompletedData.js +1 -1
- package/dist/openapi/models/SseJobFailedData.d.ts +1 -1
- package/dist/openapi/models/SseJobFailedData.js +1 -1
- package/dist/openapi/models/SseMultiOutputCompletion.d.ts +60 -0
- package/dist/openapi/models/SseMultiOutputCompletion.js +51 -0
- package/dist/openapi/models/SseMultiOutputCompletionMetrics.d.ts +38 -0
- package/dist/openapi/models/SseMultiOutputCompletionMetrics.js +43 -0
- package/dist/openapi/models/SseMultiOutputCompletionWithKind.d.ts +75 -0
- package/dist/openapi/models/SseMultiOutputCompletionWithKind.js +61 -0
- package/dist/openapi/models/SseMultiOutputResultEntry.d.ts +74 -0
- package/dist/openapi/models/SseMultiOutputResultEntry.js +51 -0
- package/dist/openapi/models/SseOperationCompletedData.d.ts +4 -4
- package/dist/openapi/models/SseOperationCompletedData.js +4 -4
- package/dist/openapi/models/SseOperationCompletionResult.d.ts +60 -0
- package/dist/openapi/models/SseOperationCompletionResult.js +47 -0
- package/dist/openapi/models/SseOperationFailedData.d.ts +1 -1
- package/dist/openapi/models/SseOperationFailedData.js +1 -1
- package/dist/openapi/models/SseOperationProgressData.d.ts +1 -1
- package/dist/openapi/models/SseOperationProgressData.js +1 -1
- package/dist/openapi/models/SseSingleOutputCompletion.d.ts +72 -0
- package/dist/openapi/models/SseSingleOutputCompletion.js +62 -0
- package/dist/openapi/models/SseWorkflowTerminalData.d.ts +1 -1
- package/dist/openapi/models/SseWorkflowTerminalData.js +1 -1
- package/dist/openapi/models/TierRestrictionKind.d.ts +1 -1
- package/dist/openapi/models/TierRestrictionKind.js +1 -1
- package/dist/openapi/models/TierRestrictionResponse.d.ts +20 -1
- package/dist/openapi/models/TierRestrictionResponse.js +1 -1
- package/dist/openapi/models/UploadConstraintsApplied.d.ts +1 -1
- package/dist/openapi/models/UploadConstraintsApplied.js +1 -1
- package/dist/openapi/models/UploadDurationExceedsTierResponse.d.ts +20 -1
- package/dist/openapi/models/UploadDurationExceedsTierResponse.js +1 -1
- package/dist/openapi/models/UploadFile403Response.d.ts +1 -1
- package/dist/openapi/models/UploadFile403Response.js +1 -1
- package/dist/openapi/models/UploadFile422Response.d.ts +1 -1
- package/dist/openapi/models/UploadFile422Response.js +1 -1
- package/dist/openapi/models/UploadProbeMediaMetadata.d.ts +1 -1
- package/dist/openapi/models/UploadProbeMediaMetadata.js +1 -1
- package/dist/openapi/models/UploadProbeProcessingClass.d.ts +1 -1
- package/dist/openapi/models/UploadProbeProcessingClass.js +1 -1
- package/dist/openapi/models/UploadProbeResponse.d.ts +4 -2
- package/dist/openapi/models/UploadProbeResponse.js +1 -1
- package/dist/openapi/models/UploadProbeStatus.d.ts +1 -1
- package/dist/openapi/models/UploadProbeStatus.js +1 -1
- package/dist/openapi/models/UploadProbeSuccessEnvelope.d.ts +56 -0
- package/dist/openapi/models/UploadProbeSuccessEnvelope.js +54 -0
- package/dist/openapi/models/UploadResponse.d.ts +1 -1
- package/dist/openapi/models/UploadResponse.js +1 -1
- package/dist/openapi/models/UploadSizeExceedsTierResponse.d.ts +20 -1
- package/dist/openapi/models/UploadSizeExceedsTierResponse.js +1 -1
- package/dist/openapi/models/UploadSource.d.ts +1 -1
- package/dist/openapi/models/UploadSource.js +1 -1
- package/dist/openapi/models/UploadSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/UploadSuccessEnvelope.js +1 -1
- package/dist/openapi/models/UploadThresholds.d.ts +11 -4
- package/dist/openapi/models/UploadThresholds.js +2 -2
- package/dist/openapi/models/UserTier.d.ts +1 -1
- package/dist/openapi/models/UserTier.js +1 -1
- package/dist/openapi/models/ValidationErrorEnvelope.d.ts +1 -1
- package/dist/openapi/models/ValidationErrorEnvelope.js +1 -1
- package/dist/openapi/models/ValidationErrorEnvelopeDetailsInner.d.ts +1 -1
- package/dist/openapi/models/ValidationErrorEnvelopeDetailsInner.js +1 -1
- package/dist/openapi/models/WarningType.d.ts +1 -1
- package/dist/openapi/models/WarningType.js +1 -1
- package/dist/openapi/models/WebhookOperationContext.d.ts +1 -1
- package/dist/openapi/models/WebhookOperationContext.js +1 -1
- package/dist/openapi/models/WebhookPayload.d.ts +1 -1
- package/dist/openapi/models/WebhookPayload.js +1 -1
- package/dist/openapi/models/WorkflowCancelBillingEffect.d.ts +1 -1
- package/dist/openapi/models/WorkflowCancelBillingEffect.js +1 -1
- package/dist/openapi/models/WorkflowCancelResponse.d.ts +1 -1
- package/dist/openapi/models/WorkflowCancelResponse.js +1 -1
- package/dist/openapi/models/WorkflowCancelSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/WorkflowCancelSuccessEnvelope.js +1 -1
- package/dist/openapi/models/WorkflowCreateRequest.d.ts +1 -1
- package/dist/openapi/models/WorkflowCreateRequest.js +1 -1
- package/dist/openapi/models/WorkflowCreateResponse.d.ts +1 -1
- package/dist/openapi/models/WorkflowCreateResponse.js +1 -1
- package/dist/openapi/models/WorkflowCreateSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/WorkflowCreateSuccessEnvelope.js +1 -1
- package/dist/openapi/models/WorkflowDownloadResponse.d.ts +1 -1
- package/dist/openapi/models/WorkflowDownloadResponse.js +1 -1
- package/dist/openapi/models/WorkflowDownloadSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/WorkflowDownloadSuccessEnvelope.js +1 -1
- package/dist/openapi/models/WorkflowEdge.d.ts +1 -1
- package/dist/openapi/models/WorkflowEdge.js +1 -1
- package/dist/openapi/models/WorkflowExpiredResponse.d.ts +20 -1
- package/dist/openapi/models/WorkflowExpiredResponse.js +1 -1
- package/dist/openapi/models/WorkflowPauseRequiredAction.d.ts +1 -1
- package/dist/openapi/models/WorkflowPauseRequiredAction.js +1 -1
- package/dist/openapi/models/WorkflowPausedDetail.d.ts +1 -1
- package/dist/openapi/models/WorkflowPausedDetail.js +1 -1
- package/dist/openapi/models/WorkflowPausedDetailLinks.d.ts +1 -1
- package/dist/openapi/models/WorkflowPausedDetailLinks.js +1 -1
- package/dist/openapi/models/WorkflowProcessing.d.ts +1 -1
- package/dist/openapi/models/WorkflowProcessing.js +1 -1
- package/dist/openapi/models/WorkflowResumeResponse.d.ts +1 -1
- package/dist/openapi/models/WorkflowResumeResponse.js +1 -1
- package/dist/openapi/models/WorkflowResumeSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/WorkflowResumeSuccessEnvelope.js +1 -1
- package/dist/openapi/models/WorkflowSource.d.ts +1 -1
- package/dist/openapi/models/WorkflowSource.js +1 -1
- package/dist/openapi/models/WorkflowStatus.d.ts +1 -1
- package/dist/openapi/models/WorkflowStatus.js +1 -1
- package/dist/openapi/models/WorkflowStatusResponse.d.ts +1 -1
- package/dist/openapi/models/WorkflowStatusResponse.js +1 -1
- package/dist/openapi/models/WorkflowStatusSuccessEnvelope.d.ts +1 -1
- package/dist/openapi/models/WorkflowStatusSuccessEnvelope.js +1 -1
- package/dist/openapi/models/WorkflowWarning.d.ts +1 -1
- package/dist/openapi/models/WorkflowWarning.js +1 -1
- package/dist/openapi/models/WorkflowWarningSeverity.d.ts +1 -1
- package/dist/openapi/models/WorkflowWarningSeverity.js +1 -1
- package/dist/openapi/models/index.d.ts +21 -0
- package/dist/openapi/models/index.js +21 -0
- package/dist/openapi/runtime.d.ts +1 -1
- package/dist/openapi/runtime.js +1 -1
- package/dist/operations/audio_overlay.metadata.js +4 -4
- package/dist/operations/audio_to_video.d.ts +20 -0
- package/dist/operations/audio_to_video.js +17 -0
- package/dist/operations/audio_to_video.metadata.d.ts +2 -0
- package/dist/operations/audio_to_video.metadata.js +29 -0
- package/dist/operations/audio_watermark.metadata.js +4 -4
- package/dist/operations/compress.metadata.js +3 -3
- package/dist/operations/convert.metadata.js +2 -2
- package/dist/operations/custom_luma.metadata.js +2 -2
- package/dist/operations/image_watermark.d.ts +0 -18
- package/dist/operations/image_watermark.js +0 -12
- package/dist/operations/image_watermark.metadata.js +0 -41
- package/dist/operations/index.d.ts +8 -0
- package/dist/operations/index.js +8 -0
- package/dist/operations/merge.metadata.js +3 -3
- package/dist/operations/metadata-types.d.ts +17 -0
- package/dist/operations/split.d.ts +50 -0
- package/dist/operations/split.js +34 -0
- package/dist/operations/split.metadata.d.ts +2 -0
- package/dist/operations/split.metadata.js +103 -0
- package/dist/operations/thumbnail.metadata.js +1 -1
- package/dist/operations/video_text_watermark.d.ts +31 -0
- package/dist/operations/video_text_watermark.js +22 -0
- package/dist/operations/video_text_watermark.metadata.d.ts +2 -0
- package/dist/operations/video_text_watermark.metadata.js +65 -0
- package/dist/operations/video_watermark.d.ts +18 -0
- package/dist/operations/video_watermark.js +13 -0
- package/dist/operations/video_watermark.metadata.d.ts +2 -0
- package/dist/operations/video_watermark.metadata.js +52 -0
- package/openapi/api.yaml +1543 -121
- package/operations/schemas/audio_overlay.yaml +18 -6
- package/operations/schemas/audio_to_video.yaml +122 -0
- package/operations/schemas/audio_watermark.yaml +14 -6
- package/operations/schemas/compress.yaml +10 -4
- package/operations/schemas/convert.yaml +10 -3
- package/operations/schemas/custom_luma.yaml +10 -3
- package/operations/schemas/image_watermark.yaml +15 -96
- package/operations/schemas/merge.yaml +10 -4
- package/operations/schemas/split.yaml +309 -0
- package/operations/schemas/thumbnail.yaml +16 -3
- package/operations/schemas/video_text_watermark.yaml +174 -0
- package/operations/schemas/video_watermark.yaml +136 -0
- package/package.json +8 -3
- package/dist/asyncapi/AnonymousSchema_13.d.ts +0 -6
- package/dist/asyncapi/AnonymousSchema_13.js +0 -7
- package/dist/asyncapi/AnonymousSchema_152.d.ts +0 -5
- package/dist/asyncapi/AnonymousSchema_152.js +0 -6
- package/dist/openapi/models/ExportConfig.d.ts +0 -63
- package/dist/openapi/models/ExportConfig.js +0 -59
- package/dist/openapi/models/JobInput.d.ts +0 -53
- package/dist/openapi/models/JobInput.js +0 -47
- package/dist/openapi/models/JobSource.d.ts +0 -43
- package/dist/openapi/models/JobSource.js +0 -45
- package/dist/operations/watermark.d.ts +0 -28
- package/dist/operations/watermark.js +0 -19
package/openapi/api.yaml
CHANGED
|
@@ -75,7 +75,7 @@ info:
|
|
|
75
75
|
of truth instead of hardcoding magic numbers. A runtime
|
|
76
76
|
`GET /api/uploads/limits` endpoint for dynamic discovery
|
|
77
77
|
(per-tier / per-environment overrides) is a deferred follow-up.
|
|
78
|
-
version: 2.
|
|
78
|
+
version: 2.15.3
|
|
79
79
|
contact:
|
|
80
80
|
name: API Support
|
|
81
81
|
|
|
@@ -302,7 +302,7 @@ paths:
|
|
|
302
302
|
for the remaining parts. The client uploads parts 2-N directly to S3.
|
|
303
303
|
|
|
304
304
|
**Recommended client behaviour:** chunk size
|
|
305
|
-
`UploadThresholds.multipart_chunk_size` (
|
|
305
|
+
`UploadThresholds.multipart_chunk_size` (16 MiB) with
|
|
306
306
|
`UploadThresholds.multipart_concurrency_default` parallel uploads.
|
|
307
307
|
The server returns `recommended_chunk_size` per file based on
|
|
308
308
|
first-chunk throughput; SDKs SHOULD prefer that runtime value when
|
|
@@ -311,9 +311,10 @@ paths:
|
|
|
311
311
|
**Chunk sizing strategy:**
|
|
312
312
|
- First chunk: fixed `UploadThresholds.multipart_first_chunk_size` = 8 MiB (sent to API)
|
|
313
313
|
- Remaining chunks: API calculates `recommended_chunk_size` from throughput * 5s,
|
|
314
|
-
clamped to
|
|
315
|
-
- The last part may be smaller than
|
|
316
|
-
- Maximum
|
|
314
|
+
clamped to 16 MiB–100 MiB
|
|
315
|
+
- The last part may be smaller than 16 MiB (S3 allows this for the final part)
|
|
316
|
+
- Maximum 10,000 parts per upload (the S3 multipart hard limit;
|
|
317
|
+
raised from 500 by CON-1/ADR-0011 for the 120 GB Enterprise envelope)
|
|
317
318
|
|
|
318
319
|
**Pre-signed URL TTL:**
|
|
319
320
|
Dynamic based on estimated upload duration * 2, clamped between 900s and 3600s.
|
|
@@ -343,7 +344,7 @@ paths:
|
|
|
343
344
|
first_chunk_etag: '"d8e8fca2dc0f896fd7cb4cb0031ba249"'
|
|
344
345
|
first_chunk_size_bytes: 8388608
|
|
345
346
|
total_parts: 5
|
|
346
|
-
recommended_chunk_size:
|
|
347
|
+
recommended_chunk_size: 16777216
|
|
347
348
|
presigned_urls:
|
|
348
349
|
- part_number: 2
|
|
349
350
|
url: "https://gisl-stg-euw1-input.s3.eu-west-1.amazonaws.com/uploads/...?X-Amz-Expires=1800&..."
|
|
@@ -444,6 +445,15 @@ paths:
|
|
|
444
445
|
|
|
445
446
|
The API calls S3 CompleteMultipartUpload and persists the upload record.
|
|
446
447
|
No job or workflow is created — use `POST /api/workflows` to process the file.
|
|
448
|
+
|
|
449
|
+
**Ownership enforcement** (per session-resume work, ticket
|
|
450
|
+
[`HxUmVr3Y`](https://trello.com/c/HxUmVr3Y)): when
|
|
451
|
+
`manifest.userId` is non-null, `multipart/complete` refuses
|
|
452
|
+
completion by any caller other than the original authenticator
|
|
453
|
+
(returns 403 `MULTIPART_SESSION_OWNERSHIP`). The sister
|
|
454
|
+
endpoints `/status`, `/presign`, `/keepalive` apply the same
|
|
455
|
+
rule and additionally refuse anonymous-initiated sessions
|
|
456
|
+
outright (returning 403 `MULTIPART_SESSION_AUTH_REQUIRED`).
|
|
447
457
|
operationId: multipartComplete
|
|
448
458
|
tags:
|
|
449
459
|
- Upload
|
|
@@ -479,6 +489,20 @@ paths:
|
|
|
479
489
|
example:
|
|
480
490
|
success: false
|
|
481
491
|
error: "Missing ETags for parts: 3, 5"
|
|
492
|
+
'403':
|
|
493
|
+
description: |
|
|
494
|
+
Forbidden — session's `manifest.userId` is non-null and
|
|
495
|
+
differs from the authenticated caller. Per ticket
|
|
496
|
+
[`HxUmVr3Y`](https://trello.com/c/HxUmVr3Y) ownership
|
|
497
|
+
enforcement (carried by the same controller path as the
|
|
498
|
+
three new resume endpoints).
|
|
499
|
+
content:
|
|
500
|
+
application/json:
|
|
501
|
+
schema:
|
|
502
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
503
|
+
example:
|
|
504
|
+
success: false
|
|
505
|
+
error: "MULTIPART_SESSION_OWNERSHIP"
|
|
482
506
|
'404':
|
|
483
507
|
description: Upload session not found or expired
|
|
484
508
|
content:
|
|
@@ -495,6 +519,341 @@ paths:
|
|
|
495
519
|
schema:
|
|
496
520
|
$ref: '#/components/schemas/ErrorEnvelope'
|
|
497
521
|
|
|
522
|
+
/api/uploads/multipart/{uploadId}/status:
|
|
523
|
+
get:
|
|
524
|
+
summary: Cursor over uploaded parts of an in-flight multipart session
|
|
525
|
+
description: |
|
|
526
|
+
Returns the list of parts already received by S3 for an in-flight
|
|
527
|
+
multipart session. Used by SDKs to resume an interrupted upload —
|
|
528
|
+
the client walks the cursor pages, collects which `part_number`
|
|
529
|
+
slots are filled, and re-presigns / re-uploads only the missing
|
|
530
|
+
slots via `POST /api/uploads/multipart/{uploadId}/presign`.
|
|
531
|
+
|
|
532
|
+
The response shape is a 1:1 passthrough of the S3 ListParts API —
|
|
533
|
+
`next_part_number_marker` and `is_truncated` mirror the upstream
|
|
534
|
+
wire shape verbatim (no translation layer, zero impedance
|
|
535
|
+
mismatch for SDKs that already speak S3 vocabulary).
|
|
536
|
+
|
|
537
|
+
**Authentication required.** Anonymous-initiated sessions (allowed
|
|
538
|
+
at `/initiate` today; the `8LABloaz` follow-up flips that to
|
|
539
|
+
require-auth) cannot use this endpoint and receive 403
|
|
540
|
+
`MULTIPART_SESSION_AUTH_REQUIRED`. Authenticated callers can only
|
|
541
|
+
list parts of sessions they initiated (403
|
|
542
|
+
`MULTIPART_SESSION_OWNERSHIP` otherwise).
|
|
543
|
+
|
|
544
|
+
Cursor semantics: pass `cursor=0` (default) for the first page;
|
|
545
|
+
the server returns up to `limit` parts plus `next_part_number_marker`
|
|
546
|
+
and `is_truncated`. To walk: pass each `next_part_number_marker`
|
|
547
|
+
as the next request's `cursor` until `is_truncated: false`. The
|
|
548
|
+
marker is `null` on the final page.
|
|
549
|
+
|
|
550
|
+
Completion-readiness is client-derived (walk all pages, compare
|
|
551
|
+
the count of returned parts to `total_parts`).
|
|
552
|
+
operationId: multipartStatus
|
|
553
|
+
tags:
|
|
554
|
+
- Upload
|
|
555
|
+
parameters:
|
|
556
|
+
- name: uploadId
|
|
557
|
+
in: path
|
|
558
|
+
required: true
|
|
559
|
+
description: Multipart upload session identifier from the initiate response.
|
|
560
|
+
schema:
|
|
561
|
+
$ref: '#/components/schemas/UuidV7'
|
|
562
|
+
- name: cursor
|
|
563
|
+
in: query
|
|
564
|
+
required: false
|
|
565
|
+
description: |
|
|
566
|
+
S3 ListParts `PartNumberMarker` (the part-number to start
|
|
567
|
+
listing **after**). `0` (default) returns from the first
|
|
568
|
+
part. Walk by passing each response's
|
|
569
|
+
`next_part_number_marker` until `is_truncated: false`.
|
|
570
|
+
schema:
|
|
571
|
+
type: integer
|
|
572
|
+
minimum: 0
|
|
573
|
+
maximum: 9999
|
|
574
|
+
default: 0
|
|
575
|
+
- name: limit
|
|
576
|
+
in: query
|
|
577
|
+
required: false
|
|
578
|
+
description: |
|
|
579
|
+
Page size — maximum number of parts returned per request.
|
|
580
|
+
`1000` is the default and the upstream S3 `MaxParts` cap.
|
|
581
|
+
schema:
|
|
582
|
+
type: integer
|
|
583
|
+
minimum: 1
|
|
584
|
+
maximum: 1000
|
|
585
|
+
default: 1000
|
|
586
|
+
responses:
|
|
587
|
+
'200':
|
|
588
|
+
description: Page of uploaded parts.
|
|
589
|
+
content:
|
|
590
|
+
application/json:
|
|
591
|
+
schema:
|
|
592
|
+
$ref: '#/components/schemas/MultipartStatusSuccessEnvelope'
|
|
593
|
+
example:
|
|
594
|
+
success: true
|
|
595
|
+
data:
|
|
596
|
+
upload_id: "019539ab-1111-7000-8000-000000000001"
|
|
597
|
+
multipart_upload_id: "5MqcMpgg9_pKVdoO9.X9eK0w2g3Sq5_h"
|
|
598
|
+
cloud_key: "uploads/01/019539ab-1111-7000-8000-000000000001/source"
|
|
599
|
+
total_parts: 5
|
|
600
|
+
uploaded_parts:
|
|
601
|
+
- part_number: 1
|
|
602
|
+
etag: '"d8e8fca2dc0f896fd7cb4cb0031ba249"'
|
|
603
|
+
size_bytes: 8388608
|
|
604
|
+
last_modified: "2026-05-20T13:30:00.000Z"
|
|
605
|
+
- part_number: 2
|
|
606
|
+
etag: '"7c3e2c4b6e3e7e0e8f9d1a2b3c4d5e6f"'
|
|
607
|
+
size_bytes: 16777216
|
|
608
|
+
last_modified: "2026-05-20T13:31:14.000Z"
|
|
609
|
+
next_part_number_marker: null
|
|
610
|
+
is_truncated: false
|
|
611
|
+
manifest_expires_at: "2026-05-22T13:31:14.000Z"
|
|
612
|
+
recommended_chunk_size: 16777216
|
|
613
|
+
'401':
|
|
614
|
+
description: Authentication required.
|
|
615
|
+
content:
|
|
616
|
+
application/json:
|
|
617
|
+
schema:
|
|
618
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
619
|
+
'403':
|
|
620
|
+
description: |
|
|
621
|
+
Forbidden — either the session was anonymously initiated
|
|
622
|
+
(`MULTIPART_SESSION_AUTH_REQUIRED`) or the authenticated
|
|
623
|
+
caller is not the session owner (`MULTIPART_SESSION_OWNERSHIP`).
|
|
624
|
+
content:
|
|
625
|
+
application/json:
|
|
626
|
+
schema:
|
|
627
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
628
|
+
examples:
|
|
629
|
+
auth_required:
|
|
630
|
+
summary: Anonymous-initiated session
|
|
631
|
+
value:
|
|
632
|
+
success: false
|
|
633
|
+
error: "MULTIPART_SESSION_AUTH_REQUIRED"
|
|
634
|
+
ownership:
|
|
635
|
+
summary: Session belongs to a different authenticated caller
|
|
636
|
+
value:
|
|
637
|
+
success: false
|
|
638
|
+
error: "MULTIPART_SESSION_OWNERSHIP"
|
|
639
|
+
'404':
|
|
640
|
+
description: Multipart session not found or expired.
|
|
641
|
+
content:
|
|
642
|
+
application/json:
|
|
643
|
+
schema:
|
|
644
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
645
|
+
example:
|
|
646
|
+
success: false
|
|
647
|
+
error: "MULTIPART_SESSION_NOT_FOUND"
|
|
648
|
+
'500':
|
|
649
|
+
description: Internal server error
|
|
650
|
+
content:
|
|
651
|
+
application/json:
|
|
652
|
+
schema:
|
|
653
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
654
|
+
|
|
655
|
+
/api/uploads/multipart/{uploadId}/presign:
|
|
656
|
+
post:
|
|
657
|
+
summary: Sparse re-presign of multipart parts (resume / retry)
|
|
658
|
+
description: |
|
|
659
|
+
Returns fresh pre-signed PUT URLs for a caller-supplied subset
|
|
660
|
+
of part numbers. Used by SDKs to (a) resume an interrupted
|
|
661
|
+
upload after the original presigned URLs have expired, and
|
|
662
|
+
(b) retry individual failed PUTs without re-presigning the
|
|
663
|
+
whole upload.
|
|
664
|
+
|
|
665
|
+
Part numbers MUST satisfy `2 ≤ n ≤ total_parts`. **Part 1 is
|
|
666
|
+
rejected** because the manifest stores its ETag from `/initiate`
|
|
667
|
+
— re-presigning part 1 would break the eventual
|
|
668
|
+
`multipart/complete` call. Request the list with
|
|
669
|
+
`uniqueItems`; duplicates are rejected with a 400.
|
|
670
|
+
|
|
671
|
+
At most 100 part numbers per request. SDKs paginate larger
|
|
672
|
+
sets across multiple `/presign` calls.
|
|
673
|
+
|
|
674
|
+
**Authentication required.** Same `MULTIPART_SESSION_*` codes
|
|
675
|
+
apply as on `/status`.
|
|
676
|
+
operationId: multipartPresign
|
|
677
|
+
tags:
|
|
678
|
+
- Upload
|
|
679
|
+
parameters:
|
|
680
|
+
- name: uploadId
|
|
681
|
+
in: path
|
|
682
|
+
required: true
|
|
683
|
+
description: Multipart upload session identifier from the initiate response.
|
|
684
|
+
schema:
|
|
685
|
+
$ref: '#/components/schemas/UuidV7'
|
|
686
|
+
requestBody:
|
|
687
|
+
required: true
|
|
688
|
+
content:
|
|
689
|
+
application/json:
|
|
690
|
+
schema:
|
|
691
|
+
$ref: '#/components/schemas/MultipartPresignRequest'
|
|
692
|
+
responses:
|
|
693
|
+
'200':
|
|
694
|
+
description: Pre-signed URLs returned for the requested parts.
|
|
695
|
+
content:
|
|
696
|
+
application/json:
|
|
697
|
+
schema:
|
|
698
|
+
$ref: '#/components/schemas/MultipartPresignSuccessEnvelope'
|
|
699
|
+
example:
|
|
700
|
+
success: true
|
|
701
|
+
data:
|
|
702
|
+
upload_id: "019539ab-1111-7000-8000-000000000001"
|
|
703
|
+
presigned_urls:
|
|
704
|
+
- part_number: 3
|
|
705
|
+
url: "https://gisl-stg-euw1-input.s3.eu-west-1.amazonaws.com/uploads/...?X-Amz-Expires=1800&..."
|
|
706
|
+
expires_at: "2026-05-20T14:01:14.000Z"
|
|
707
|
+
- part_number: 5
|
|
708
|
+
url: "https://gisl-stg-euw1-input.s3.eu-west-1.amazonaws.com/uploads/...?X-Amz-Expires=1800&..."
|
|
709
|
+
expires_at: "2026-05-20T14:01:14.000Z"
|
|
710
|
+
'400':
|
|
711
|
+
description: |
|
|
712
|
+
Validation failed — e.g. body too large, malformed JSON,
|
|
713
|
+
`part_numbers` empty / >100, contains duplicates, contains
|
|
714
|
+
`1`, contains values outside `[2, total_parts]`.
|
|
715
|
+
content:
|
|
716
|
+
application/json:
|
|
717
|
+
schema:
|
|
718
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
719
|
+
example:
|
|
720
|
+
success: false
|
|
721
|
+
error: "part_numbers must contain unique values in [2, total_parts]; part 1 is sealed"
|
|
722
|
+
'401':
|
|
723
|
+
description: Authentication required.
|
|
724
|
+
content:
|
|
725
|
+
application/json:
|
|
726
|
+
schema:
|
|
727
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
728
|
+
'403':
|
|
729
|
+
description: |
|
|
730
|
+
Forbidden — either the session was anonymously initiated
|
|
731
|
+
(`MULTIPART_SESSION_AUTH_REQUIRED`) or the authenticated
|
|
732
|
+
caller is not the session owner (`MULTIPART_SESSION_OWNERSHIP`).
|
|
733
|
+
content:
|
|
734
|
+
application/json:
|
|
735
|
+
schema:
|
|
736
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
737
|
+
examples:
|
|
738
|
+
auth_required:
|
|
739
|
+
value:
|
|
740
|
+
success: false
|
|
741
|
+
error: "MULTIPART_SESSION_AUTH_REQUIRED"
|
|
742
|
+
ownership:
|
|
743
|
+
value:
|
|
744
|
+
success: false
|
|
745
|
+
error: "MULTIPART_SESSION_OWNERSHIP"
|
|
746
|
+
'404':
|
|
747
|
+
description: Multipart session not found or expired.
|
|
748
|
+
content:
|
|
749
|
+
application/json:
|
|
750
|
+
schema:
|
|
751
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
752
|
+
example:
|
|
753
|
+
success: false
|
|
754
|
+
error: "MULTIPART_SESSION_NOT_FOUND"
|
|
755
|
+
'422':
|
|
756
|
+
description: |
|
|
757
|
+
Session no longer accepts re-presign requests because the
|
|
758
|
+
assembled object would exceed the S3 multipart capacity
|
|
759
|
+
cap. Pre-S3 server-side capacity gate; distinct from
|
|
760
|
+
tier-quota rejections at `/initiate` time.
|
|
761
|
+
content:
|
|
762
|
+
application/json:
|
|
763
|
+
schema:
|
|
764
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
765
|
+
example:
|
|
766
|
+
success: false
|
|
767
|
+
error: "FILE_TOO_LARGE_FOR_MULTIPART"
|
|
768
|
+
'500':
|
|
769
|
+
description: Internal server error
|
|
770
|
+
content:
|
|
771
|
+
application/json:
|
|
772
|
+
schema:
|
|
773
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
774
|
+
|
|
775
|
+
/api/uploads/multipart/{uploadId}/keepalive:
|
|
776
|
+
post:
|
|
777
|
+
summary: Refresh the multipart session manifest TTL
|
|
778
|
+
description: |
|
|
779
|
+
Resets the session manifest's TTL to 48 h ahead of now. The
|
|
780
|
+
server uses an atomic Redis `EXPIRE`; the operation is
|
|
781
|
+
idempotent — calling it multiple times in succession produces
|
|
782
|
+
the same effective TTL window.
|
|
783
|
+
|
|
784
|
+
SDKs SHOULD call this periodically on resume flows (e.g. once
|
|
785
|
+
per minute while a resumable upload is paused) to prevent the
|
|
786
|
+
manifest from lapsing. The manifest TTL is decoupled from
|
|
787
|
+
individual presigned-URL TTLs (which are typically 900s–3600s);
|
|
788
|
+
re-presigning expired URLs requires the manifest still be
|
|
789
|
+
alive.
|
|
790
|
+
|
|
791
|
+
Empty request body.
|
|
792
|
+
|
|
793
|
+
**Authentication required.** Same `MULTIPART_SESSION_*` codes
|
|
794
|
+
apply as on `/status` and `/presign`.
|
|
795
|
+
operationId: multipartKeepalive
|
|
796
|
+
tags:
|
|
797
|
+
- Upload
|
|
798
|
+
parameters:
|
|
799
|
+
- name: uploadId
|
|
800
|
+
in: path
|
|
801
|
+
required: true
|
|
802
|
+
description: Multipart upload session identifier from the initiate response.
|
|
803
|
+
schema:
|
|
804
|
+
$ref: '#/components/schemas/UuidV7'
|
|
805
|
+
responses:
|
|
806
|
+
'200':
|
|
807
|
+
description: Manifest TTL refreshed; new expiry returned.
|
|
808
|
+
content:
|
|
809
|
+
application/json:
|
|
810
|
+
schema:
|
|
811
|
+
$ref: '#/components/schemas/MultipartKeepaliveSuccessEnvelope'
|
|
812
|
+
example:
|
|
813
|
+
success: true
|
|
814
|
+
data:
|
|
815
|
+
upload_id: "019539ab-1111-7000-8000-000000000001"
|
|
816
|
+
manifest_expires_at: "2026-05-22T13:31:14.000Z"
|
|
817
|
+
'401':
|
|
818
|
+
description: Authentication required.
|
|
819
|
+
content:
|
|
820
|
+
application/json:
|
|
821
|
+
schema:
|
|
822
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
823
|
+
'403':
|
|
824
|
+
description: |
|
|
825
|
+
Forbidden — either the session was anonymously initiated
|
|
826
|
+
(`MULTIPART_SESSION_AUTH_REQUIRED`) or the authenticated
|
|
827
|
+
caller is not the session owner (`MULTIPART_SESSION_OWNERSHIP`).
|
|
828
|
+
content:
|
|
829
|
+
application/json:
|
|
830
|
+
schema:
|
|
831
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
832
|
+
examples:
|
|
833
|
+
auth_required:
|
|
834
|
+
value:
|
|
835
|
+
success: false
|
|
836
|
+
error: "MULTIPART_SESSION_AUTH_REQUIRED"
|
|
837
|
+
ownership:
|
|
838
|
+
value:
|
|
839
|
+
success: false
|
|
840
|
+
error: "MULTIPART_SESSION_OWNERSHIP"
|
|
841
|
+
'404':
|
|
842
|
+
description: Multipart session not found or expired.
|
|
843
|
+
content:
|
|
844
|
+
application/json:
|
|
845
|
+
schema:
|
|
846
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
847
|
+
example:
|
|
848
|
+
success: false
|
|
849
|
+
error: "MULTIPART_SESSION_NOT_FOUND"
|
|
850
|
+
'500':
|
|
851
|
+
description: Internal server error
|
|
852
|
+
content:
|
|
853
|
+
application/json:
|
|
854
|
+
schema:
|
|
855
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
856
|
+
|
|
498
857
|
/api/uploads/{id}/metadata:
|
|
499
858
|
get:
|
|
500
859
|
summary: Get file metadata
|
|
@@ -609,82 +968,92 @@ paths:
|
|
|
609
968
|
responses:
|
|
610
969
|
'200':
|
|
611
970
|
description: |
|
|
612
|
-
Probe completed. The `probe_status` field indicates
|
|
971
|
+
Probe completed. The `data.probe_status` field indicates
|
|
613
972
|
whether the file is workflow-ready (`ok`) or has issues
|
|
614
973
|
that warrant exclusion / re-upload.
|
|
615
974
|
content:
|
|
616
975
|
application/json:
|
|
617
976
|
schema:
|
|
618
|
-
$ref: '#/components/schemas/
|
|
977
|
+
$ref: '#/components/schemas/UploadProbeSuccessEnvelope'
|
|
619
978
|
examples:
|
|
620
979
|
ok_short_form:
|
|
621
980
|
summary: Short-form clip probed cleanly
|
|
622
981
|
value:
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
982
|
+
success: true
|
|
983
|
+
data:
|
|
984
|
+
file_id: "019539ab-1111-7000-8000-000000000001"
|
|
985
|
+
probe_status: "ok"
|
|
986
|
+
media_metadata:
|
|
987
|
+
duration_seconds: 187
|
|
988
|
+
width: 1920
|
|
989
|
+
height: 1080
|
|
990
|
+
codec: "h264"
|
|
991
|
+
container: "mp4"
|
|
992
|
+
audio_layout: "stereo"
|
|
993
|
+
probed_at: "2026-04-26T13:50:00Z"
|
|
994
|
+
processing_class_pre_assignment: "short_form"
|
|
634
995
|
ok_long_form:
|
|
635
996
|
summary: Long-form clip — full M2 union populated (video + audio fields)
|
|
636
997
|
value:
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
998
|
+
success: true
|
|
999
|
+
data:
|
|
1000
|
+
file_id: "019539ab-1111-7000-8000-000000000002"
|
|
1001
|
+
probe_status: "ok"
|
|
1002
|
+
media_metadata:
|
|
1003
|
+
duration_seconds: 5400
|
|
1004
|
+
width: 3840
|
|
1005
|
+
height: 2160
|
|
1006
|
+
codec: "h265"
|
|
1007
|
+
audio_codec: "aac"
|
|
1008
|
+
container: "mp4"
|
|
1009
|
+
fps: 23.976
|
|
1010
|
+
bitrate_bps: 18000000
|
|
1011
|
+
audio_layout: "stereo"
|
|
1012
|
+
channels: 2
|
|
1013
|
+
sample_rate_hz: 48000
|
|
1014
|
+
probed_at: "2026-04-26T13:50:00Z"
|
|
1015
|
+
processing_class_pre_assignment: "long_form"
|
|
653
1016
|
corrupt:
|
|
654
1017
|
summary: File header damaged — caller should exclude
|
|
655
1018
|
value:
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
1019
|
+
success: true
|
|
1020
|
+
data:
|
|
1021
|
+
file_id: "019539ab-1111-7000-8000-000000000003"
|
|
1022
|
+
probe_status: "corrupt"
|
|
1023
|
+
media_metadata:
|
|
1024
|
+
probed_at: "2026-04-26T13:50:00Z"
|
|
1025
|
+
processing_class_pre_assignment: "blocked"
|
|
661
1026
|
unsupported_codec:
|
|
662
1027
|
summary: Container readable but codec unsupported
|
|
663
1028
|
value:
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
1029
|
+
success: true
|
|
1030
|
+
data:
|
|
1031
|
+
file_id: "019539ab-1111-7000-8000-000000000004"
|
|
1032
|
+
probe_status: "unsupported_codec"
|
|
1033
|
+
media_metadata:
|
|
1034
|
+
duration_seconds: 600
|
|
1035
|
+
width: 1280
|
|
1036
|
+
height: 720
|
|
1037
|
+
codec: "prores_4444"
|
|
1038
|
+
container: "mov"
|
|
1039
|
+
probed_at: "2026-04-26T13:50:00Z"
|
|
1040
|
+
processing_class_pre_assignment: "blocked"
|
|
674
1041
|
blocked_by_tier:
|
|
675
1042
|
summary: Free-tier caller probes a long-form clip
|
|
676
1043
|
value:
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
1044
|
+
success: true
|
|
1045
|
+
data:
|
|
1046
|
+
file_id: "019539ab-1111-7000-8000-000000000005"
|
|
1047
|
+
probe_status: "ok"
|
|
1048
|
+
media_metadata:
|
|
1049
|
+
duration_seconds: 5400
|
|
1050
|
+
width: 1920
|
|
1051
|
+
height: 1080
|
|
1052
|
+
codec: "h264"
|
|
1053
|
+
container: "mp4"
|
|
1054
|
+
audio_layout: "stereo"
|
|
1055
|
+
probed_at: "2026-04-26T13:50:00Z"
|
|
1056
|
+
processing_class_pre_assignment: "blocked"
|
|
688
1057
|
'401':
|
|
689
1058
|
description: Authentication required.
|
|
690
1059
|
content:
|
|
@@ -762,12 +1131,21 @@ paths:
|
|
|
762
1131
|
side-effect dependencies that don't surface as `from`
|
|
763
1132
|
references).
|
|
764
1133
|
|
|
765
|
-
**Default operation:** if `operations` is omitted
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
1134
|
+
**Default operation:** if `operations` is omitted — or
|
|
1135
|
+
explicitly empty (`[]`) — on a single-input job with
|
|
1136
|
+
`source: { type: upload, ... }`, the default is
|
|
1137
|
+
`[{ "type": "compress" }]` with default options for the
|
|
1138
|
+
detected MIME type. Multi-input jobs must always specify
|
|
769
1139
|
operations explicitly.
|
|
770
1140
|
|
|
1141
|
+
**Compression opt-out:** V2 has no `skip_compression` flag —
|
|
1142
|
+
`operations[]` *is* the chain. To opt a job out of
|
|
1143
|
+
compression, send an explicit non-empty `operations[]` that
|
|
1144
|
+
does not include `compress`; on a single-input upload job an
|
|
1145
|
+
empty `[]` does *not* opt out (it is treated as omitted and
|
|
1146
|
+
still receives the implicit `compress` — see above). Per
|
|
1147
|
+
[ADR-0004](../docs/decisions/0004-job-shape.md).
|
|
1148
|
+
|
|
771
1149
|
**Multi-input constraint:** multi-input jobs (`inputs[]`) must
|
|
772
1150
|
have exactly one operation, which must be a multi-input type
|
|
773
1151
|
(`merge`, `archive`, `image_watermark`, `custom_luma`, or
|
|
@@ -1077,7 +1455,7 @@ paths:
|
|
|
1077
1455
|
error: "Upload not found: 019539ab-1111-7000-8000-999999999999"
|
|
1078
1456
|
'422':
|
|
1079
1457
|
description: |
|
|
1080
|
-
Semantically invalid request.
|
|
1458
|
+
Semantically invalid request. One of:
|
|
1081
1459
|
|
|
1082
1460
|
- Generic validation error (unknown operation type, invalid
|
|
1083
1461
|
option combinations, cyclic dependency in workflow_edges,
|
|
@@ -1090,6 +1468,22 @@ paths:
|
|
|
1090
1468
|
with `error_type: feature_not_available`. Per ADR-0001
|
|
1091
1469
|
§1.3 Tension 1 rule, the server MUST honour tagged
|
|
1092
1470
|
availability.
|
|
1471
|
+
- Processing-class band-ceiling overflow — returned as
|
|
1472
|
+
`ProcessingClassExceedsBandResponse` with `error_type:
|
|
1473
|
+
processing_class_exceeds_band`. Fires when one or more
|
|
1474
|
+
jobs cannot be classified because input size/duration
|
|
1475
|
+
exceeds the `long_form` (or `long_form_re_encode`)
|
|
1476
|
+
ceiling under the caller's effective per-tier caps
|
|
1477
|
+
(`per_tier_constraints` overlay per
|
|
1478
|
+
[ADR-0011](../docs/decisions/0011-per-tier-processing-class-constraints.md)).
|
|
1479
|
+
Per-violation `required_tier` names the tier (if any)
|
|
1480
|
+
whose `per_tier_constraints` would accommodate the
|
|
1481
|
+
request (`null` = no tier resolves, e.g. enterprise
|
|
1482
|
+
already at the 120 GB hard ceiling). Distinct from
|
|
1483
|
+
`TierRestrictionResponse` (403, request-level upload
|
|
1484
|
+
quota — see [ADR-0012](../docs/decisions/0012-processing-class-band-reject-envelope.md)
|
|
1485
|
+
for the band-vs-tier split). Per ADR-0001 §F6
|
|
1486
|
+
batched-violations rule, `violations[]` is fail-all.
|
|
1093
1487
|
- Re-encode required (per ticket I16-CONS, Trello
|
|
1094
1488
|
`7nCZXEru`). Returned for `merge.video` jobs with
|
|
1095
1489
|
`re_encode_mode: never` when the compatibility probe
|
|
@@ -1108,27 +1502,49 @@ paths:
|
|
|
1108
1502
|
Backward-compatibility note: the prior 422 shape
|
|
1109
1503
|
(`ValidationErrorEnvelope`) is preserved unchanged — its
|
|
1110
1504
|
`details[]` array is the structural signature consumers
|
|
1111
|
-
duck-type against.
|
|
1112
|
-
|
|
1113
|
-
`
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
`
|
|
1124
|
-
|
|
1125
|
-
|
|
1505
|
+
duck-type against. `FeatureNotAvailableResponse` carries
|
|
1506
|
+
`error_type: feature_not_available` + `violations[]`;
|
|
1507
|
+
`ProcessingClassExceedsBandResponse` carries `error_type:
|
|
1508
|
+
processing_class_exceeds_band` + `violations[]`.
|
|
1509
|
+
`ProbePendingResponse` carries `error_type: probe_pending`
|
|
1510
|
+
+ `job_ref` (and NO `violations[]` / `details[]`), emitted
|
|
1511
|
+
when the probe-pending gate is on and a job's upload has
|
|
1512
|
+
not yet been probed. The `REQUIRES_REENCODE` flavour reuses
|
|
1513
|
+
`ValidationErrorEnvelope`
|
|
1514
|
+
(a user-fixable validation error in the same family as
|
|
1515
|
+
`INVALID_OPTIONS`) and is distinguished by the stable
|
|
1516
|
+
`error: "REQUIRES_REENCODE"` string code rather than a new
|
|
1517
|
+
`error_type` enum value. Branches are distinguishable by
|
|
1518
|
+
required-field shape (`details` vs `error_type` value), so
|
|
1519
|
+
plain `oneOf` matches without a discriminator object — see
|
|
1520
|
+
`openapi/api.yaml` §"FEATURE AVAILABILITY ENVELOPES"
|
|
1521
|
+
commentary for the convention rationale (no discriminator
|
|
1522
|
+
here because `ValidationErrorEnvelope` has no `error_type`
|
|
1523
|
+
field; OpenAPI 3.1 discriminators require the property to
|
|
1524
|
+
be present on every branch).
|
|
1525
|
+
headers:
|
|
1526
|
+
Retry-After:
|
|
1527
|
+
required: false
|
|
1528
|
+
description: |
|
|
1529
|
+
Optional, best-effort. Present only on the
|
|
1530
|
+
`probe_pending` branch — suggested seconds to wait
|
|
1531
|
+
before re-polling the upload probe and retrying the
|
|
1532
|
+
workflow. Delta-seconds (RFC 9110), mirroring the 429
|
|
1533
|
+
login path's `Retry-After` convention. Absent until the
|
|
1534
|
+
server-side probe-staleness bound (API `e1Idv6UL`)
|
|
1535
|
+
lands; consumers MUST treat absence as "retry on your
|
|
1536
|
+
own backoff schedule."
|
|
1537
|
+
schema:
|
|
1538
|
+
type: integer
|
|
1539
|
+
minimum: 0
|
|
1126
1540
|
content:
|
|
1127
1541
|
application/json:
|
|
1128
1542
|
schema:
|
|
1129
1543
|
oneOf:
|
|
1130
1544
|
- $ref: '#/components/schemas/ValidationErrorEnvelope'
|
|
1131
1545
|
- $ref: '#/components/schemas/FeatureNotAvailableResponse'
|
|
1546
|
+
- $ref: '#/components/schemas/ProcessingClassExceedsBandResponse'
|
|
1547
|
+
- $ref: '#/components/schemas/ProbePendingResponse'
|
|
1132
1548
|
examples:
|
|
1133
1549
|
validation_error:
|
|
1134
1550
|
summary: Generic validation error (legacy shape)
|
|
@@ -1155,6 +1571,56 @@ paths:
|
|
|
1155
1571
|
documentation_url: "https://docs.giveitsmaller.com/operations/audio_overlay"
|
|
1156
1572
|
- feature: "operation.merge.mime_group.image.option.transition.dissolve"
|
|
1157
1573
|
availability: "experimental"
|
|
1574
|
+
probe_pending:
|
|
1575
|
+
summary: |
|
|
1576
|
+
Probe-pending gate is on and a single-op video
|
|
1577
|
+
compress references an upload whose server-side
|
|
1578
|
+
probe has not yet landed. Client polls the upload
|
|
1579
|
+
probe endpoint, then re-POSTs the workflow. The
|
|
1580
|
+
`Retry-After` header (5s here) hints the poll delay.
|
|
1581
|
+
value:
|
|
1582
|
+
success: false
|
|
1583
|
+
error: "Upload probe has not completed; poll the upload probe endpoint and retry"
|
|
1584
|
+
error_type: "probe_pending"
|
|
1585
|
+
job_ref: "job_0"
|
|
1586
|
+
message_key: "error.probe_pending"
|
|
1587
|
+
processing_class_exceeds_band_combined_size:
|
|
1588
|
+
summary: |
|
|
1589
|
+
merge job whose summed inputs (130 GB) exceed the
|
|
1590
|
+
Enterprise long_form_re_encode ceiling (120 GB
|
|
1591
|
+
hard cap per ADR-0011). Terminal — no tier
|
|
1592
|
+
resolves it; `required_tier` is null.
|
|
1593
|
+
value:
|
|
1594
|
+
success: false
|
|
1595
|
+
error: "Workflow contains inputs that exceed the long-form processing-class ceiling"
|
|
1596
|
+
error_type: "processing_class_exceeds_band"
|
|
1597
|
+
violations:
|
|
1598
|
+
- reason: "combined_size_exceeds_long_form"
|
|
1599
|
+
job_ref: "stitched"
|
|
1600
|
+
operation: "merge"
|
|
1601
|
+
processing_class: "long_form_re_encode"
|
|
1602
|
+
actual: 130000000000
|
|
1603
|
+
ceiling: 120000000000
|
|
1604
|
+
required_tier: null
|
|
1605
|
+
documentation_url: "https://docs.giveitsmaller.com/processing-class/long-form"
|
|
1606
|
+
processing_class_exceeds_band_single_input_duration:
|
|
1607
|
+
summary: |
|
|
1608
|
+
compress.video job whose single input duration
|
|
1609
|
+
(15 hours = 54000s) exceeds the Pro long_form
|
|
1610
|
+
`max_input_duration` (PT12H = 43200s). Upgrade to
|
|
1611
|
+
Enterprise resolves the duration cap.
|
|
1612
|
+
value:
|
|
1613
|
+
success: false
|
|
1614
|
+
error: "Workflow contains inputs that exceed the long-form processing-class ceiling"
|
|
1615
|
+
error_type: "processing_class_exceeds_band"
|
|
1616
|
+
violations:
|
|
1617
|
+
- reason: "input_duration_exceeds_long_form"
|
|
1618
|
+
job_ref: "job_0"
|
|
1619
|
+
operation: "compress"
|
|
1620
|
+
processing_class: "long_form"
|
|
1621
|
+
actual: 54000
|
|
1622
|
+
ceiling: 43200
|
|
1623
|
+
required_tier: "enterprise"
|
|
1158
1624
|
requires_reencode:
|
|
1159
1625
|
summary: merge.video re_encode_mode=never with incompatible inputs (I16-CONS)
|
|
1160
1626
|
value:
|
|
@@ -1343,6 +1809,35 @@ paths:
|
|
|
1343
1809
|
event: workflow.completed
|
|
1344
1810
|
data: {"workflow_id":"wf-uuid","status":"completed"}
|
|
1345
1811
|
```
|
|
1812
|
+
|
|
1813
|
+
**Reconnect & delivery semantics:**
|
|
1814
|
+
|
|
1815
|
+
Delivery is **at-least-once per connection with no client-driven
|
|
1816
|
+
resume**. The server does **not** read an inbound `Last-Event-ID`
|
|
1817
|
+
header; each connection re-derives state from scratch and replays
|
|
1818
|
+
every underlying stream from the start. Consequently **terminal events
|
|
1819
|
+
(`operation.completed` / `operation.failed`, `job.completed` /
|
|
1820
|
+
`job.failed`, `workflow.completed` / `workflow.failed` /
|
|
1821
|
+
`workflow.partially_failed`) are re-delivered on every (re)connection**.
|
|
1822
|
+
Within a single connection events are not duplicated (the cursor
|
|
1823
|
+
advances as events are sent), so duplicates only arise across
|
|
1824
|
+
reconnects. Clients MUST therefore treat the stream as idempotent and
|
|
1825
|
+
dedupe terminal events themselves (e.g. by `operation_id` + event type,
|
|
1826
|
+
or by workflow/job terminal status) rather than relying on
|
|
1827
|
+
resume-from-cursor. Resume-from-`Last-Event-ID` is **not** implemented;
|
|
1828
|
+
if added later it will be a separate, explicitly-specified feature.
|
|
1829
|
+
|
|
1830
|
+
**`id:` field (SSE event id):** emitted **only on operation frames**
|
|
1831
|
+
(`operation.progress` / `operation.completed` / `operation.failed`),
|
|
1832
|
+
where it carries the underlying stream's event id. **Transition frames**
|
|
1833
|
+
(`job.completed` / `job.failed`, `workflow.*`) carry **no `id:`**.
|
|
1834
|
+
Because there is no `Last-Event-ID` resume, any emitted `id:` is
|
|
1835
|
+
informational only — clients cannot use it to resume a stream.
|
|
1836
|
+
|
|
1837
|
+
**Framing vs payload:** the `Sse*Data` component schemas describe only
|
|
1838
|
+
the `data:` JSON payload of each event. The SSE envelope framing itself
|
|
1839
|
+
(the `id:` and `event:` lines) is transport-level and intentionally
|
|
1840
|
+
**not** schema-described.
|
|
1346
1841
|
operationId: streamWorkflowEvents
|
|
1347
1842
|
tags:
|
|
1348
1843
|
- Workflow
|
|
@@ -2796,6 +3291,25 @@ components:
|
|
|
2796
3291
|
`REQUIRES_REENCODE`). Canonical English; never localised.
|
|
2797
3292
|
SDKs duck-type on this field for typed error-branch
|
|
2798
3293
|
helpers.
|
|
3294
|
+
|
|
3295
|
+
Multipart-session resume codes (per ticket
|
|
3296
|
+
[`HxUmVr3Y`](https://trello.com/c/HxUmVr3Y), V2.10.0):
|
|
3297
|
+
- `MULTIPART_SESSION_NOT_FOUND` (404) — upload_id does
|
|
3298
|
+
not match an in-flight session (expired / never
|
|
3299
|
+
existed / wrong account namespace). Fired by /status,
|
|
3300
|
+
/presign, /keepalive.
|
|
3301
|
+
- `MULTIPART_SESSION_OWNERSHIP` (403) — authenticated
|
|
3302
|
+
caller is not the session owner. Fired by /status,
|
|
3303
|
+
/presign, /keepalive, /complete (when manifest.userId
|
|
3304
|
+
is non-null and differs).
|
|
3305
|
+
- `MULTIPART_SESSION_AUTH_REQUIRED` (403) — session was
|
|
3306
|
+
anonymously initiated; the three resume endpoints
|
|
3307
|
+
require authentication. The `8LABloaz` follow-up will
|
|
3308
|
+
flip `/initiate` to also require auth.
|
|
3309
|
+
- `FILE_TOO_LARGE_FOR_MULTIPART` (422) — assembled object
|
|
3310
|
+
would exceed the S3 multipart capacity cap. Pre-S3
|
|
3311
|
+
server-side capacity gate; distinct from tier-quota
|
|
3312
|
+
rejections (`upload_size_exceeds_tier`).
|
|
2799
3313
|
message:
|
|
2800
3314
|
type: string
|
|
2801
3315
|
description: |
|
|
@@ -3056,6 +3570,62 @@ components:
|
|
|
3056
3570
|
additionalProperties:
|
|
3057
3571
|
$ref: '#/components/schemas/PerValueAvailabilityEntry'
|
|
3058
3572
|
|
|
3573
|
+
PerRoleCardinality:
|
|
3574
|
+
type: object
|
|
3575
|
+
description: |
|
|
3576
|
+
Map of role-name → `PerRoleCardinalityEntry`. Attached to
|
|
3577
|
+
a role-based multi-input operation's `per_role_cardinality`
|
|
3578
|
+
field to declare the required and maximum input count per
|
|
3579
|
+
role. **Cardinality overlay, not availability overlay** —
|
|
3580
|
+
sits alongside `PerValueAvailability` / `PerMimeAvailability`
|
|
3581
|
+
structurally but expresses a different concern.
|
|
3582
|
+
|
|
3583
|
+
Keys MUST be a subset of the `JobInputRole` enum
|
|
3584
|
+
(CI-checked by `scripts/check-per-role-cardinality.py`).
|
|
3585
|
+
The script additionally enforces arithmetic-consistency:
|
|
3586
|
+
`sum(role.min) == OperationSchemaDefinition.min_inputs`
|
|
3587
|
+
and `sum(role.max) == OperationSchemaDefinition.max_inputs`
|
|
3588
|
+
— this is the load-bearing invariant that makes the
|
|
3589
|
+
primitive useful.
|
|
3590
|
+
|
|
3591
|
+
Absence of `per_role_cardinality` on a role-based op keeps
|
|
3592
|
+
the current prose-only semantics (image_watermark /
|
|
3593
|
+
audio_overlay / custom_luma encode their role rules in
|
|
3594
|
+
prose at `JobInputRole`'s description today; migration to
|
|
3595
|
+
predicate form is per-op follow-up work).
|
|
3596
|
+
|
|
3597
|
+
Per ticket [`SlluxMBN`](https://trello.com/c/SlluxMBN) /
|
|
3598
|
+
ADR-0015. Consumed by `OperationInputRoleValidator` in
|
|
3599
|
+
`compression_api` (rule table becomes data-driven) and by
|
|
3600
|
+
SDK generators when emitting typed role-binding helpers.
|
|
3601
|
+
additionalProperties:
|
|
3602
|
+
$ref: '#/components/schemas/PerRoleCardinalityEntry'
|
|
3603
|
+
|
|
3604
|
+
PerRoleCardinalityEntry:
|
|
3605
|
+
type: object
|
|
3606
|
+
description: |
|
|
3607
|
+
Per-role cardinality entry. `min: 0` makes the role optional.
|
|
3608
|
+
`max: 1` is the most common upper bound (one base, one
|
|
3609
|
+
overlay); future role-based ops may declare higher maxima
|
|
3610
|
+
(e.g. multi-overlay video composites). Both fields default to
|
|
3611
|
+
`1` when absent on a role key — but consumers SHOULD treat
|
|
3612
|
+
absence of either field as a contract bug surfaced by
|
|
3613
|
+
`scripts/check-per-role-cardinality.py` rather than silently
|
|
3614
|
+
defaulting.
|
|
3615
|
+
required:
|
|
3616
|
+
- min
|
|
3617
|
+
- max
|
|
3618
|
+
properties:
|
|
3619
|
+
min:
|
|
3620
|
+
type: integer
|
|
3621
|
+
minimum: 0
|
|
3622
|
+
description: Minimum input count for this role (0 = optional).
|
|
3623
|
+
max:
|
|
3624
|
+
type: integer
|
|
3625
|
+
minimum: 1
|
|
3626
|
+
description: |
|
|
3627
|
+
Maximum input count for this role. MUST be >= `min`.
|
|
3628
|
+
|
|
3059
3629
|
# ============================================
|
|
3060
3630
|
# EXTERNAL SOURCES + DESTINATIONS
|
|
3061
3631
|
# ============================================
|
|
@@ -4274,8 +4844,12 @@ components:
|
|
|
4274
4844
|
rejection.
|
|
4275
4845
|
|
|
4276
4846
|
The 422 response is delivered alongside `ValidationErrorEnvelope`
|
|
4277
|
-
|
|
4278
|
-
|
|
4847
|
+
and `ProcessingClassExceedsBandResponse` via a naked `oneOf`
|
|
4848
|
+
(duck-typed on required-field shape — `details` vs `error_type`
|
|
4849
|
+
value: `feature_not_available` vs `processing_class_exceeds_band`).
|
|
4850
|
+
No discriminator object is used because `ValidationErrorEnvelope`
|
|
4851
|
+
has no `error_type` field. See the 422 response on
|
|
4852
|
+
`POST /api/workflows`.
|
|
4279
4853
|
allOf:
|
|
4280
4854
|
- $ref: '#/components/schemas/ErrorEnvelope'
|
|
4281
4855
|
- type: object
|
|
@@ -4299,31 +4873,278 @@ components:
|
|
|
4299
4873
|
items:
|
|
4300
4874
|
$ref: '#/components/schemas/FeatureViolation'
|
|
4301
4875
|
|
|
4302
|
-
|
|
4876
|
+
ProbePendingResponse:
|
|
4303
4877
|
description: |
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4878
|
+
422 response on `POST /api/workflows` when the probe-pending
|
|
4879
|
+
gate (API `av1J0rEF`, shipped behind a default-OFF feature flag)
|
|
4880
|
+
is enabled and a job references an upload whose server-side
|
|
4881
|
+
probe has not yet completed at workflow-create time. Rather than
|
|
4882
|
+
silently routing the job as `short_form` (which hard-fails long
|
|
4883
|
+
video clips), the server rejects with this envelope so the
|
|
4884
|
+
client can recover deterministically.
|
|
4885
|
+
|
|
4886
|
+
**Recovery contract.** Poll `POST /api/uploads/{id}/probe` for
|
|
4887
|
+
the pending upload until its `probe_status` is terminal
|
|
4888
|
+
(`ok` → re-`POST /api/workflows` the same request; `corrupt` /
|
|
4889
|
+
`unsupported_codec` → surface the probe error, do not retry).
|
|
4890
|
+
The `Retry-After` response header (when present) carries the
|
|
4891
|
+
suggested delay in seconds before the next poll/retry.
|
|
4892
|
+
|
|
4893
|
+
Delivered alongside `ValidationErrorEnvelope`,
|
|
4894
|
+
`FeatureNotAvailableResponse`, and
|
|
4895
|
+
`ProcessingClassExceedsBandResponse` via the naked `oneOf` on
|
|
4896
|
+
the 422 response — duck-typed on required-field shape: this
|
|
4897
|
+
branch is the only one carrying `error_type: probe_pending`
|
|
4898
|
+
and it has neither `details` (ValidationErrorEnvelope) nor
|
|
4899
|
+
`violations` (the other two typed envelopes), so it matches
|
|
4900
|
+
exactly one branch.
|
|
4312
4901
|
allOf:
|
|
4313
4902
|
- $ref: '#/components/schemas/ErrorEnvelope'
|
|
4314
4903
|
- type: object
|
|
4315
4904
|
required:
|
|
4316
4905
|
- error_type
|
|
4317
|
-
-
|
|
4906
|
+
- job_ref
|
|
4318
4907
|
properties:
|
|
4319
4908
|
error_type:
|
|
4320
4909
|
type: string
|
|
4321
4910
|
enum:
|
|
4322
|
-
-
|
|
4323
|
-
description: Discriminator for the
|
|
4324
|
-
|
|
4325
|
-
type:
|
|
4326
|
-
|
|
4911
|
+
- probe_pending
|
|
4912
|
+
description: Discriminator for the 422 oneOf. Always `probe_pending`.
|
|
4913
|
+
job_ref:
|
|
4914
|
+
type: string
|
|
4915
|
+
description: |
|
|
4916
|
+
Workflow-local identifier of the job whose upload-probe
|
|
4917
|
+
has not landed — `JobDefinition.id` if the caller
|
|
4918
|
+
supplied one, else the auto-generated `job_N` token.
|
|
4919
|
+
Mirrors `ProcessingClassBandViolation.job_ref`; NOT
|
|
4920
|
+
`format: uuid` because workflow-create rejects fire
|
|
4921
|
+
before server-side UUIDs are assigned.
|
|
4922
|
+
example: "job_0"
|
|
4923
|
+
|
|
4924
|
+
ProcessingClassRejectReason:
|
|
4925
|
+
type: string
|
|
4926
|
+
description: |
|
|
4927
|
+
Why a job cannot be classified — input size/duration exceeds
|
|
4928
|
+
the `long_form` (or `long_form_re_encode`) ceiling under the
|
|
4929
|
+
caller's effective per-tier caps (per
|
|
4930
|
+
[ADR-0011](../docs/decisions/0011-per-tier-processing-class-constraints.md)
|
|
4931
|
+
`per_tier_constraints`). Distinct from `ProcessingClassReason`
|
|
4932
|
+
(which describes WHY a job got its assigned class — success-
|
|
4933
|
+
path advisory).
|
|
4934
|
+
|
|
4935
|
+
Reasons are split by the violated constraint key on the
|
|
4936
|
+
processing-class block (per `schemas/FORMAT.md`
|
|
4937
|
+
§"`processing_class:` block"):
|
|
4938
|
+
|
|
4939
|
+
- `input_size_exceeds_long_form` /
|
|
4940
|
+
`input_duration_exceeds_long_form`: a **single input**
|
|
4941
|
+
exceeds the per-input ceiling (`max_input_size_bytes` /
|
|
4942
|
+
`max_input_duration`). Applies to single-input operations
|
|
4943
|
+
(compress, convert, thumbnail, text_watermark,
|
|
4944
|
+
audio_watermark) AND per-input checks on multi-input
|
|
4945
|
+
operations with per-input caps (image_watermark,
|
|
4946
|
+
custom_luma, audio_overlay).
|
|
4947
|
+
- `combined_size_exceeds_long_form` /
|
|
4948
|
+
`combined_duration_exceeds_long_form`: the **summed** inputs
|
|
4949
|
+
exceed the multi-input combined ceiling
|
|
4950
|
+
(`max_total_input_size_bytes` / `max_total_duration`).
|
|
4951
|
+
Applies to operations whose `processing_class.<class>.
|
|
4952
|
+
constraints` carries `max_total_*` — merge today.
|
|
4953
|
+
enum:
|
|
4954
|
+
- input_size_exceeds_long_form
|
|
4955
|
+
- input_duration_exceeds_long_form
|
|
4956
|
+
- combined_size_exceeds_long_form
|
|
4957
|
+
- combined_duration_exceeds_long_form
|
|
4958
|
+
|
|
4959
|
+
ProcessingClassBandViolation:
|
|
4960
|
+
type: object
|
|
4961
|
+
description: |
|
|
4962
|
+
One band-ceiling overflow on a workflow-create reject. Carries
|
|
4963
|
+
the I26 localisation quad on the violation (mirrors
|
|
4964
|
+
`FeatureViolation`); envelope-level localisation rides via
|
|
4965
|
+
`allOf [ErrorEnvelope]` on `ProcessingClassExceedsBandResponse`.
|
|
4966
|
+
|
|
4967
|
+
`job_ref`, `actual`, `ceiling`, `operation`, and
|
|
4968
|
+
`processing_class` are REQUIRED — the server always knows them
|
|
4969
|
+
at reject time and consumers rely on them to (a) correlate
|
|
4970
|
+
fail-all violations back to the offending job in multi-job
|
|
4971
|
+
workflows and (b) render "X exceeded by Y" without re-deriving
|
|
4972
|
+
caps from the per-tier overlay.
|
|
4973
|
+
required:
|
|
4974
|
+
- reason
|
|
4975
|
+
- job_ref
|
|
4976
|
+
- operation
|
|
4977
|
+
- processing_class
|
|
4978
|
+
- actual
|
|
4979
|
+
- ceiling
|
|
4980
|
+
properties:
|
|
4981
|
+
reason:
|
|
4982
|
+
$ref: '#/components/schemas/ProcessingClassRejectReason'
|
|
4983
|
+
job_ref:
|
|
4984
|
+
type: string
|
|
4985
|
+
description: |
|
|
4986
|
+
Workflow-local job identifier — `JobDefinition.id` if the
|
|
4987
|
+
caller supplied one, otherwise the auto-generated `job_N`
|
|
4988
|
+
positional token assigned by the server during request
|
|
4989
|
+
validation (e.g. `job_0`, `job_1`). Workflow-create rejects
|
|
4990
|
+
fire BEFORE persisted server UUIDs are assigned; `job_ref`
|
|
4991
|
+
is the request-local handle that survives across reject
|
|
4992
|
+
and (later) success paths. Per `JobDefinition.id` pattern
|
|
4993
|
+
+ auto-generation rules.
|
|
4994
|
+
example: "stitched"
|
|
4995
|
+
input_index:
|
|
4996
|
+
type: integer
|
|
4997
|
+
minimum: 0
|
|
4998
|
+
description: |
|
|
4999
|
+
0-based ordinal into `JobDefinition.inputs[]` identifying
|
|
5000
|
+
the specific input that violated the per-input ceiling.
|
|
5001
|
+
Set ONLY on `input_*_exceeds_long_form` reasons for
|
|
5002
|
+
multi-input operations; omitted on single-input
|
|
5003
|
+
operations (no positional ambiguity) and on
|
|
5004
|
+
`combined_*_exceeds_long_form` reasons (whole-job
|
|
5005
|
+
violation across all inputs).
|
|
5006
|
+
operation:
|
|
5007
|
+
$ref: '#/components/schemas/OperationType'
|
|
5008
|
+
description: Operation type that triggered the band-ceiling reject.
|
|
5009
|
+
processing_class:
|
|
5010
|
+
$ref: '#/components/schemas/ProcessingClass'
|
|
5011
|
+
description: |
|
|
5012
|
+
The class whose ceiling was exceeded — typically `long_form`
|
|
5013
|
+
or `long_form_re_encode`.
|
|
5014
|
+
actual:
|
|
5015
|
+
type: integer
|
|
5016
|
+
minimum: 0
|
|
5017
|
+
description: |
|
|
5018
|
+
Observed value. Bytes for `*_size_exceeds_long_form`
|
|
5019
|
+
reasons; whole seconds for `*_duration_exceeds_long_form`
|
|
5020
|
+
reasons.
|
|
5021
|
+
ceiling:
|
|
5022
|
+
type: integer
|
|
5023
|
+
minimum: 0
|
|
5024
|
+
description: |
|
|
5025
|
+
Effective per-tier ceiling for this caller (same units as
|
|
5026
|
+
`actual`). The binding cap after `per_tier_constraints`
|
|
5027
|
+
overlay; lets consumers render "X exceeded by Y" without
|
|
5028
|
+
re-deriving caps from the per-tier overlay.
|
|
5029
|
+
required_tier:
|
|
5030
|
+
description: |
|
|
5031
|
+
Optional. When a HIGHER tier exists whose
|
|
5032
|
+
`per_tier_constraints` would accommodate this request, the
|
|
5033
|
+
server SHOULD set `required_tier` to that tier — consumers
|
|
5034
|
+
can offer an upgrade nudge. `null` (or omitted) means
|
|
5035
|
+
**no tier resolves** the overflow (e.g. enterprise already
|
|
5036
|
+
hits the 120 GB hard ceiling per
|
|
5037
|
+
[ADR-0011](../docs/decisions/0011-per-tier-processing-class-constraints.md)
|
|
5038
|
+
D1–D4).
|
|
5039
|
+
|
|
5040
|
+
Distinct from `TierRestrictionResponse.required_tier`
|
|
5041
|
+
which names a tier whose request-level upload cap
|
|
5042
|
+
satisfies the request — this field names a tier whose
|
|
5043
|
+
long-form processing-class cap satisfies it. Per
|
|
5044
|
+
[ADR-0012](../docs/decisions/0012-processing-class-band-reject-envelope.md)
|
|
5045
|
+
for the band-vs-tier split.
|
|
5046
|
+
oneOf:
|
|
5047
|
+
- $ref: '#/components/schemas/UserTier'
|
|
5048
|
+
- type: 'null'
|
|
5049
|
+
documentation_url:
|
|
5050
|
+
type: string
|
|
5051
|
+
format: uri
|
|
5052
|
+
description: Optional link to processing-class documentation.
|
|
5053
|
+
message_key:
|
|
5054
|
+
type: string
|
|
5055
|
+
description: Per I26. See `ErrorEnvelope.message_key`.
|
|
5056
|
+
message:
|
|
5057
|
+
type: string
|
|
5058
|
+
description: |
|
|
5059
|
+
Per I26. Human-readable, localised per `Accept-Language`.
|
|
5060
|
+
Never parse for control flow.
|
|
5061
|
+
locale:
|
|
5062
|
+
type: string
|
|
5063
|
+
description: BCP 47 locale tag. See `ErrorEnvelope.locale`.
|
|
5064
|
+
message_params:
|
|
5065
|
+
type: object
|
|
5066
|
+
additionalProperties: true
|
|
5067
|
+
description: |
|
|
5068
|
+
Per I26. Optional interpolation values for the localised
|
|
5069
|
+
`message`. Excludes cost numbers.
|
|
5070
|
+
|
|
5071
|
+
ProcessingClassExceedsBandResponse:
|
|
5072
|
+
description: |
|
|
5073
|
+
422 response body when one or more jobs cannot be classified
|
|
5074
|
+
because input size/duration exceeds the `long_form` (or
|
|
5075
|
+
`long_form_re_encode`) ceiling under the caller's effective
|
|
5076
|
+
per-tier caps (per
|
|
5077
|
+
[ADR-0011](../docs/decisions/0011-per-tier-processing-class-constraints.md)
|
|
5078
|
+
`per_tier_constraints`).
|
|
5079
|
+
|
|
5080
|
+
Distinct from `TierRestrictionResponse` (403, request-level
|
|
5081
|
+
tier-quota — resolvable by upload-size reduction or quota
|
|
5082
|
+
change) and from `FeatureNotAvailableResponse` (422, feature
|
|
5083
|
+
tagged not-yet-shipped — resolvable by waiting for the
|
|
5084
|
+
availability flip). Resolution path is per-violation:
|
|
5085
|
+
`required_tier` on each `ProcessingClassBandViolation` names
|
|
5086
|
+
the tier (if any) whose `per_tier_constraints` would
|
|
5087
|
+
accommodate the request; `null` means terminal (e.g. enterprise
|
|
5088
|
+
already at the 120 GB hard ceiling).
|
|
5089
|
+
|
|
5090
|
+
Per
|
|
5091
|
+
[ADR-0012](../docs/decisions/0012-processing-class-band-reject-envelope.md)
|
|
5092
|
+
for the band-vs-tier rationale and routing rule (why this
|
|
5093
|
+
envelope is 422, not an extension of `TierRestrictionResponse`
|
|
5094
|
+
on 403).
|
|
5095
|
+
|
|
5096
|
+
Delivered on `POST /api/workflows` 422 in a naked `oneOf`
|
|
5097
|
+
alongside `ValidationErrorEnvelope` and
|
|
5098
|
+
`FeatureNotAvailableResponse` — branches distinguished by
|
|
5099
|
+
required-field shape (`details` vs `error_type` value).
|
|
5100
|
+
allOf:
|
|
5101
|
+
- $ref: '#/components/schemas/ErrorEnvelope'
|
|
5102
|
+
- type: object
|
|
5103
|
+
required:
|
|
5104
|
+
- error_type
|
|
5105
|
+
- violations
|
|
5106
|
+
properties:
|
|
5107
|
+
error_type:
|
|
5108
|
+
type: string
|
|
5109
|
+
enum:
|
|
5110
|
+
- processing_class_exceeds_band
|
|
5111
|
+
description: Discriminator for the 422 oneOf. Always `processing_class_exceeds_band` for this envelope.
|
|
5112
|
+
violations:
|
|
5113
|
+
type: array
|
|
5114
|
+
minItems: 1
|
|
5115
|
+
description: |
|
|
5116
|
+
One entry per offending job/input. Per ADR-0001 §F6
|
|
5117
|
+
batched-violations rule, multiple violations in a
|
|
5118
|
+
single request are ALL returned here (fail-all, not
|
|
5119
|
+
fail-fast).
|
|
5120
|
+
items:
|
|
5121
|
+
$ref: '#/components/schemas/ProcessingClassBandViolation'
|
|
5122
|
+
|
|
5123
|
+
FeatureTierRestrictedResponse:
|
|
5124
|
+
description: |
|
|
5125
|
+
403 response body when a workflow references one or more features
|
|
5126
|
+
gated by a higher subscription tier than the caller has.
|
|
5127
|
+
|
|
5128
|
+
Distinct from `TierRestrictionResponse` (also 403): this envelope
|
|
5129
|
+
is per-feature granularity (operation / mime_group / option /
|
|
5130
|
+
per_value); `TierRestrictionResponse` is request-level (file size
|
|
5131
|
+
or MIME). The two envelopes are discriminated by `error_type` at
|
|
5132
|
+
the response `oneOf` level.
|
|
5133
|
+
allOf:
|
|
5134
|
+
- $ref: '#/components/schemas/ErrorEnvelope'
|
|
5135
|
+
- type: object
|
|
5136
|
+
required:
|
|
5137
|
+
- error_type
|
|
5138
|
+
- violations
|
|
5139
|
+
properties:
|
|
5140
|
+
error_type:
|
|
5141
|
+
type: string
|
|
5142
|
+
enum:
|
|
5143
|
+
- feature_tier_restricted
|
|
5144
|
+
description: Discriminator for the 403 oneOf. Always `feature_tier_restricted`.
|
|
5145
|
+
violations:
|
|
5146
|
+
type: array
|
|
5147
|
+
minItems: 1
|
|
4327
5148
|
description: |
|
|
4328
5149
|
One entry per tier-gated feature. Each `FeatureViolation`
|
|
4329
5150
|
MUST set `required_tier` to the tier that would satisfy
|
|
@@ -4509,7 +5330,7 @@ components:
|
|
|
4509
5330
|
- thumbnail_office: Office document (DOCX/XLSX/PPTX/ODT/ODS/ODP)
|
|
4510
5331
|
thumbnail sub-type. Backed by a dedicated LibreOffice Lambda.
|
|
4511
5332
|
Not yet emitted.
|
|
4512
|
-
- image_watermark: Image overlay (file or external_source) onto a base
|
|
5333
|
+
- image_watermark: Image overlay (file or external_source) onto a base IMAGE asset. Multi-input (Path B with role: base + overlay). Stable for static-image bases (jpeg/png/webp); animated GIF is advertised as `planned` via the `image_gif` mime_group — dispatch returns `feature_not_available` (422) until Lambda support ships. Video bases are NOT supported by image_watermark — use the dedicated `video_watermark` operation per ADR-0013. Per ADR-0004 + I4-CONS + I5 (Trello AKZiOXnd).
|
|
4513
5334
|
- text_watermark: Text overlay rendered onto an image (Liberation Sans). Single-input. Per ADR-0004 + I4-CONS.
|
|
4514
5335
|
- merge: Concatenate/combine multiple files into one (images, video, audio). Multi-input. Image inputs merge into animated GIF or slideshow video; image collage/grid and PDF concatenation are not supported by the V1 Lambda.
|
|
4515
5336
|
- archive: Bundle files into ZIP/tar.gz (all types). Multi-input.
|
|
@@ -4517,6 +5338,10 @@ components:
|
|
|
4517
5338
|
- custom_luma: Apply a caller-uploaded luma matte to a base video for a custom luma-matte transition effect. Multi-input (`role: base` + `role: transition_mask`). `availability: planned` + `required_tier: pro`; dispatch returns `feature_not_available` (422) until Lambda ships. Distinct from FFmpeg `xfade=custom` (which is an expression, not an operation). Per ticket I29 (Trello EPUE5Vs1).
|
|
4518
5339
|
- audio_overlay: Mix a secondary audio asset over a primary audio or video base (DJ tags, podcast intros/outros, station IDs, jingles). Multi-input (`role: base` + `role: overlay`). `availability: planned`; dispatch returns `feature_not_available` (422) until Lambda ships. **NOT** the same as `audio_watermark` — that operation is steganographic (imperceptible identifier embedded for ownership tracking), tracked separately by I20. Per ticket I19 (Trello Xr3Z4GBF).
|
|
4519
5340
|
- audio_watermark: Embed a steganographic forensic watermark into an audio asset (or a video's audio track) — Cinavia / Resemble PerTh territory. Single-input. `availability: planned` + `required_tier: enterprise`; dispatch returns `feature_not_available` (422) until Lambda ships. Pairs with `POST /api/audio-watermark/decode` for own-watermarks-only extraction. Per ticket I20 (Trello omiCq7Vn).
|
|
5341
|
+
- audio_to_video: Produce a video from an audio input plus an OPTIONAL still image overlay. Multi-input role-based with the first OPTIONAL role on the contract (`role: base` audio required, `role: overlay` image 0..1 — see `per_role_cardinality`). When overlay is omitted, the video uses a solid background colour. `availability: planned`; dispatch returns `feature_not_available` (422) until Lambda ships. Per ticket [`SlluxMBN`](https://trello.com/c/SlluxMBN) + ADR-0015 (introduces `per_role_cardinality` vocab).
|
|
5342
|
+
- video_watermark: Apply an image overlay onto a base video via FFmpeg's `overlay` filter. Multi-input role-based (`role: base` video + `role: overlay` image, exactly one of each per `per_role_cardinality`). Re-encode required; audio stream-copy passthrough. Distinct from `image_watermark` (pure-Rust/image-only). `availability: planned`; dispatch returns `feature_not_available` (422) until Lambda ships. Per ticket [`4NrRPCgh`](https://trello.com/c/4NrRPCgh) + ADR-0013.
|
|
5343
|
+
- video_text_watermark: Render a text overlay onto a base video via FFmpeg's `drawtext` filter. Single-input — text and styling in options. Same `watermark_mode` (single/tiled), anchor + margin vocab as `text_watermark`. Re-encode required; audio stream-copy passthrough. `availability: planned`; dispatch returns `feature_not_available` (422) until Lambda ships. Per ticket [`4NrRPCgh`](https://trello.com/c/4NrRPCgh) + ADR-0013.
|
|
5344
|
+
- split: Fan one input file into N outputs across GIF / PDF / audio / video MIME families. Single-input per-mime-group catalog (mirrors merge/convert): GIF uses `frame_range` (REQUIRED) + `output_format`; PDF uses `page_range` OR `page_groups` (mutually exclusive); audio + video use a `mode` discriminator (interval/count/cut_points) + numeric-seconds wire format + `precision` flag (fast/exact). 200-output hard cap per ADR-0009 §D5 with per-mode preflight math; output naming `output-001..output-200`. Long-form video routes to a separate `split-video-fargate` worker via `processing_class`. `availability: planned`; dispatch returns `feature_not_available` (422) until Lambda ships. Per ticket [`vKI0CFDu`](https://trello.com/c/vKI0CFDu) + ADR-0014.
|
|
4520
5345
|
|
|
4521
5346
|
Both the legacy `thumbnail` value and the four sub-type values
|
|
4522
5347
|
are valid routing targets today during the thumbnail migration
|
|
@@ -4541,6 +5366,10 @@ components:
|
|
|
4541
5366
|
- custom_luma
|
|
4542
5367
|
- audio_overlay
|
|
4543
5368
|
- audio_watermark
|
|
5369
|
+
- audio_to_video
|
|
5370
|
+
- video_watermark
|
|
5371
|
+
- video_text_watermark
|
|
5372
|
+
- split
|
|
4544
5373
|
|
|
4545
5374
|
OperationInputModel:
|
|
4546
5375
|
type: string
|
|
@@ -4548,8 +5377,9 @@ components:
|
|
|
4548
5377
|
Whether the operation accepts a single file or multiple files:
|
|
4549
5378
|
- single: One input file (compress, thumbnail, thumbnail_image,
|
|
4550
5379
|
thumbnail_video, thumbnail_document, thumbnail_office,
|
|
4551
|
-
text_watermark, convert, audio_watermark
|
|
4552
|
-
|
|
5380
|
+
text_watermark, convert, audio_watermark,
|
|
5381
|
+
video_text_watermark, split)
|
|
5382
|
+
- multi: Multiple input files (merge, archive, image_watermark, custom_luma, audio_overlay, audio_to_video, video_watermark). audio_to_video is the first role-based op with an OPTIONAL role (min_inputs=1, max_inputs=2 — see `per_role_cardinality`); video_watermark mirrors `image_watermark`'s 2-required pattern on video bases.
|
|
4553
5383
|
enum:
|
|
4554
5384
|
- single
|
|
4555
5385
|
- multi
|
|
@@ -4634,11 +5464,18 @@ components:
|
|
|
4634
5464
|
multipart_chunk_size:
|
|
4635
5465
|
type: integer
|
|
4636
5466
|
format: int64
|
|
4637
|
-
const:
|
|
5467
|
+
const: 16777216
|
|
4638
5468
|
description: |
|
|
4639
5469
|
Recommended chunk size in bytes for multipart upload
|
|
4640
|
-
chunks (
|
|
4641
|
-
|
|
5470
|
+
chunks (16 MiB / 16,777,216 bytes — 1024-based). Raised
|
|
5471
|
+
from 5 MiB by CON-1 (ADR-0011): S3 caps a multipart
|
|
5472
|
+
upload at 10,000 parts, and the Enterprise envelope is a
|
|
5473
|
+
120 GB hard ceiling. At 16 MiB a 120 GiB object needs
|
|
5474
|
+
7,680 parts (≤ 10,000, inside AWS's 16–64 MB recommended
|
|
5475
|
+
band); 5 MiB would need 24,576 and 10 MiB 12,288 — both
|
|
5476
|
+
exceed the S3 limit. **Wire-incompatible change** — SDKs
|
|
5477
|
+
pin this as a compile-time constant, so CON-1 and SDK-2
|
|
5478
|
+
ship as a non-independently-mergeable pair. The server's
|
|
4642
5479
|
`MultipartInitiateResponse` returns a
|
|
4643
5480
|
`recommended_chunk_size` per file based on first-chunk
|
|
4644
5481
|
throughput; SDKs SHOULD prefer that runtime value when
|
|
@@ -4807,27 +5644,43 @@ components:
|
|
|
4807
5644
|
total_parts:
|
|
4808
5645
|
type: integer
|
|
4809
5646
|
minimum: 2
|
|
4810
|
-
maximum:
|
|
5647
|
+
maximum: 10000
|
|
4811
5648
|
description: |
|
|
4812
5649
|
Total number of parts. The client slices the remaining file into
|
|
4813
5650
|
exactly (total_parts - 1) chunks using recommended_chunk_size.
|
|
4814
|
-
The last chunk may be smaller.
|
|
5651
|
+
The last chunk may be smaller. Maximum raised 500 → 10,000 by
|
|
5652
|
+
CON-1 (ADR-0011) — 10,000 is the S3 multipart hard part limit;
|
|
5653
|
+
500 contract-capped uploads at ≈ 50 GB, below the 120 GB
|
|
5654
|
+
Enterprise envelope.
|
|
4815
5655
|
example: 5
|
|
4816
5656
|
recommended_chunk_size:
|
|
4817
5657
|
type: integer
|
|
4818
|
-
minimum:
|
|
5658
|
+
minimum: 16777216
|
|
4819
5659
|
maximum: 104857600
|
|
4820
5660
|
description: |
|
|
4821
5661
|
Chunk size in bytes for remaining parts. Calculated from first chunk
|
|
4822
|
-
throughput * 5s target, clamped to
|
|
4823
|
-
smaller than
|
|
4824
|
-
|
|
5662
|
+
throughput * 5s target, clamped to 16 MiB–100 MiB. The last chunk
|
|
5663
|
+
may be smaller than 16 MiB. Minimum raised 5 MiB → 16 MiB by CON-1
|
|
5664
|
+
(ADR-0011) so the runtime value never falls below the
|
|
5665
|
+
`UploadThresholds.multipart_chunk_size` constant SDKs fall back to
|
|
5666
|
+
(the S3 10,000-part limit at the 120 GB Enterprise ceiling).
|
|
5667
|
+
example: 16777216
|
|
4825
5668
|
presigned_urls:
|
|
4826
5669
|
type: array
|
|
4827
5670
|
description: |
|
|
4828
5671
|
Pre-signed S3 PUT URLs for parts 2 through total_parts.
|
|
4829
5672
|
Each URL accepts a PUT request with raw chunk bytes as body.
|
|
4830
5673
|
Collect the ETag from each S3 response for the complete request.
|
|
5674
|
+
|
|
5675
|
+
NOTE (CON-1/ADR-0011): with `total_parts` now bounded by the
|
|
5676
|
+
S3 hard limit (10,000), a maximal Enterprise upload implies a
|
|
5677
|
+
large URL set. The server is NOT required to return every URL
|
|
5678
|
+
in one synchronous response — bounded-batch / paginated URL
|
|
5679
|
+
delivery and resumable re-fetch are owned by API-2
|
|
5680
|
+
(durable upload session) and SDK-3 (presigned batching +
|
|
5681
|
+
paginated ListParts). Consumers MUST NOT assume a single
|
|
5682
|
+
initiate response carries all `total_parts - 1` URLs at the
|
|
5683
|
+
high end of the range; treat this array as the first batch.
|
|
4831
5684
|
items:
|
|
4832
5685
|
$ref: '#/components/schemas/PresignedUrlPart'
|
|
4833
5686
|
constraints_applied:
|
|
@@ -4940,6 +5793,249 @@ components:
|
|
|
4940
5793
|
data:
|
|
4941
5794
|
$ref: '#/components/schemas/MultipartCompleteResponse'
|
|
4942
5795
|
|
|
5796
|
+
# ============================================
|
|
5797
|
+
# MULTIPART SESSION RESUME SCHEMAS (HxUmVr3Y)
|
|
5798
|
+
# ============================================
|
|
5799
|
+
|
|
5800
|
+
MultipartPartListing:
|
|
5801
|
+
type: object
|
|
5802
|
+
description: |
|
|
5803
|
+
One uploaded part as reported by the S3 multipart ListParts
|
|
5804
|
+
API. The /status response carries an array of these. Mirrors
|
|
5805
|
+
the S3 wire shape verbatim so the response is a 1:1 passthrough
|
|
5806
|
+
with no translation layer.
|
|
5807
|
+
required:
|
|
5808
|
+
- part_number
|
|
5809
|
+
- etag
|
|
5810
|
+
- size_bytes
|
|
5811
|
+
- last_modified
|
|
5812
|
+
properties:
|
|
5813
|
+
part_number:
|
|
5814
|
+
type: integer
|
|
5815
|
+
minimum: 1
|
|
5816
|
+
maximum: 10000
|
|
5817
|
+
description: |
|
|
5818
|
+
S3 multipart part number. Part 1 is always present in a
|
|
5819
|
+
healthy session (uploaded synchronously at `/initiate`);
|
|
5820
|
+
parts 2–N follow.
|
|
5821
|
+
etag:
|
|
5822
|
+
type: string
|
|
5823
|
+
description: |
|
|
5824
|
+
ETag returned by S3 for the part. Quoted MD5 hex by default;
|
|
5825
|
+
preserve quotes verbatim as S3 emits them.
|
|
5826
|
+
example: '"d8e8fca2dc0f896fd7cb4cb0031ba249"'
|
|
5827
|
+
size_bytes:
|
|
5828
|
+
type: integer
|
|
5829
|
+
format: int64
|
|
5830
|
+
minimum: 0
|
|
5831
|
+
description: Part size in bytes (as reported by S3).
|
|
5832
|
+
last_modified:
|
|
5833
|
+
type: string
|
|
5834
|
+
format: date-time
|
|
5835
|
+
description: ISO-8601 timestamp from S3 ListParts `LastModified`.
|
|
5836
|
+
|
|
5837
|
+
MultipartStatusResponse:
|
|
5838
|
+
type: object
|
|
5839
|
+
description: |
|
|
5840
|
+
Resume-state snapshot for an in-flight multipart session. The
|
|
5841
|
+
`data` payload on `GET /api/uploads/multipart/{uploadId}/status`.
|
|
5842
|
+
required:
|
|
5843
|
+
- upload_id
|
|
5844
|
+
- multipart_upload_id
|
|
5845
|
+
- cloud_key
|
|
5846
|
+
- total_parts
|
|
5847
|
+
- uploaded_parts
|
|
5848
|
+
- next_part_number_marker
|
|
5849
|
+
- is_truncated
|
|
5850
|
+
- manifest_expires_at
|
|
5851
|
+
- recommended_chunk_size
|
|
5852
|
+
properties:
|
|
5853
|
+
upload_id:
|
|
5854
|
+
$ref: '#/components/schemas/UuidV7'
|
|
5855
|
+
description: Session identifier (matches the path `uploadId` and the initiate response `upload_id`).
|
|
5856
|
+
multipart_upload_id:
|
|
5857
|
+
type: string
|
|
5858
|
+
description: |
|
|
5859
|
+
S3 multipart upload identifier returned by `CreateMultipartUpload`.
|
|
5860
|
+
Opaque to API consumers; emitted for diagnostic visibility
|
|
5861
|
+
(SDK logs / dashboards correlating against AWS CloudTrail).
|
|
5862
|
+
cloud_key:
|
|
5863
|
+
type: string
|
|
5864
|
+
description: |
|
|
5865
|
+
S3 object key under which the assembled object will be
|
|
5866
|
+
stored on `multipart/complete`. Opaque to consumers.
|
|
5867
|
+
total_parts:
|
|
5868
|
+
type: integer
|
|
5869
|
+
minimum: 2
|
|
5870
|
+
maximum: 10000
|
|
5871
|
+
description: |
|
|
5872
|
+
Total number of parts the client must upload to complete
|
|
5873
|
+
the session. Same value as `MultipartInitiateResponse.total_parts`
|
|
5874
|
+
and stable for the lifetime of the session.
|
|
5875
|
+
uploaded_parts:
|
|
5876
|
+
type: array
|
|
5877
|
+
description: |
|
|
5878
|
+
Parts already present in S3 for this session, as reported
|
|
5879
|
+
by S3 ListParts at request time. May be empty (no parts
|
|
5880
|
+
uploaded yet) or partial (resume mid-upload). Order is the
|
|
5881
|
+
S3-native part-number ascending.
|
|
5882
|
+
items:
|
|
5883
|
+
$ref: '#/components/schemas/MultipartPartListing'
|
|
5884
|
+
next_part_number_marker:
|
|
5885
|
+
description: |
|
|
5886
|
+
S3 ListParts cursor — pass this as the next request's
|
|
5887
|
+
`cursor` query parameter to fetch the following page.
|
|
5888
|
+
`null` on the final page (or when `is_truncated: false`).
|
|
5889
|
+
Mirrors the S3 `NextPartNumberMarker` field verbatim.
|
|
5890
|
+
|
|
5891
|
+
Upper bound matches the request `cursor` query parameter
|
|
5892
|
+
range (`0..9999`) so SDKs can round-trip the marker
|
|
5893
|
+
verbatim — `total_parts` caps at 10,000 and the cursor
|
|
5894
|
+
semantically means "list after part N", so the highest
|
|
5895
|
+
reachable marker is 9,999 (any cursor of 10,000 would
|
|
5896
|
+
return an empty page).
|
|
5897
|
+
oneOf:
|
|
5898
|
+
- type: integer
|
|
5899
|
+
minimum: 0
|
|
5900
|
+
maximum: 9999
|
|
5901
|
+
- type: 'null'
|
|
5902
|
+
is_truncated:
|
|
5903
|
+
type: boolean
|
|
5904
|
+
description: |
|
|
5905
|
+
`true` when more pages remain; `false` on the final page.
|
|
5906
|
+
Mirrors the S3 ListParts `IsTruncated` field verbatim.
|
|
5907
|
+
manifest_expires_at:
|
|
5908
|
+
description: |
|
|
5909
|
+
ISO-8601 expiry timestamp of the session manifest. `null`
|
|
5910
|
+
when the TTL has lapsed or was not initialised — in that
|
|
5911
|
+
case, callers SHOULD invoke
|
|
5912
|
+
`POST /api/uploads/multipart/{uploadId}/keepalive` to
|
|
5913
|
+
re-establish a 48 h window before re-presigning. The
|
|
5914
|
+
manifest TTL is decoupled from individual presigned-URL
|
|
5915
|
+
TTLs.
|
|
5916
|
+
oneOf:
|
|
5917
|
+
- type: string
|
|
5918
|
+
format: date-time
|
|
5919
|
+
- type: 'null'
|
|
5920
|
+
recommended_chunk_size:
|
|
5921
|
+
type: integer
|
|
5922
|
+
minimum: 16777216
|
|
5923
|
+
maximum: 104857600
|
|
5924
|
+
description: |
|
|
5925
|
+
Chunk size (bytes) the server recommends for any remaining
|
|
5926
|
+
parts in this session — identical to
|
|
5927
|
+
`MultipartInitiateResponse.recommended_chunk_size` (16 MiB
|
|
5928
|
+
floor / 100 MiB ceiling per CON-1 / ADR-0011). Returned on
|
|
5929
|
+
every page so the client doesn't need to retain the
|
|
5930
|
+
initiate response across a resume.
|
|
5931
|
+
|
|
5932
|
+
MultipartStatusSuccessEnvelope:
|
|
5933
|
+
type: object
|
|
5934
|
+
required:
|
|
5935
|
+
- success
|
|
5936
|
+
- data
|
|
5937
|
+
properties:
|
|
5938
|
+
success:
|
|
5939
|
+
type: boolean
|
|
5940
|
+
enum: [true]
|
|
5941
|
+
data:
|
|
5942
|
+
$ref: '#/components/schemas/MultipartStatusResponse'
|
|
5943
|
+
|
|
5944
|
+
MultipartPresignRequest:
|
|
5945
|
+
type: object
|
|
5946
|
+
description: |
|
|
5947
|
+
Caller-supplied subset of part numbers to re-presign. Request
|
|
5948
|
+
body for `POST /api/uploads/multipart/{uploadId}/presign`.
|
|
5949
|
+
required:
|
|
5950
|
+
- part_numbers
|
|
5951
|
+
properties:
|
|
5952
|
+
part_numbers:
|
|
5953
|
+
type: array
|
|
5954
|
+
minItems: 1
|
|
5955
|
+
maxItems: 100
|
|
5956
|
+
uniqueItems: true
|
|
5957
|
+
description: |
|
|
5958
|
+
Part numbers to re-presign. Each entry MUST satisfy
|
|
5959
|
+
`2 ≤ n ≤ total_parts` from the initiate response —
|
|
5960
|
+
**Part 1 is rejected** because the manifest stores its
|
|
5961
|
+
ETag from `/initiate` and re-presigning would break the
|
|
5962
|
+
eventual `multipart/complete` call. Cap of 100 entries
|
|
5963
|
+
per request; SDKs paginate larger resume sets across
|
|
5964
|
+
multiple `/presign` calls.
|
|
5965
|
+
items:
|
|
5966
|
+
type: integer
|
|
5967
|
+
minimum: 2
|
|
5968
|
+
maximum: 10000
|
|
5969
|
+
|
|
5970
|
+
MultipartPresignResponse:
|
|
5971
|
+
type: object
|
|
5972
|
+
description: |
|
|
5973
|
+
Pre-signed URLs for the parts requested via
|
|
5974
|
+
`MultipartPresignRequest.part_numbers`. The `data` payload on
|
|
5975
|
+
`POST /api/uploads/multipart/{uploadId}/presign`.
|
|
5976
|
+
required:
|
|
5977
|
+
- upload_id
|
|
5978
|
+
- presigned_urls
|
|
5979
|
+
properties:
|
|
5980
|
+
upload_id:
|
|
5981
|
+
$ref: '#/components/schemas/UuidV7'
|
|
5982
|
+
description: Session identifier (echoes the path `uploadId`).
|
|
5983
|
+
presigned_urls:
|
|
5984
|
+
type: array
|
|
5985
|
+
minItems: 1
|
|
5986
|
+
maxItems: 100
|
|
5987
|
+
description: |
|
|
5988
|
+
One pre-signed PUT URL per requested part number, in the
|
|
5989
|
+
same order as `MultipartPresignRequest.part_numbers`. Each
|
|
5990
|
+
item carries `part_number` + `url` + `expires_at` —
|
|
5991
|
+
same shape as `MultipartInitiateResponse.presigned_urls[]`.
|
|
5992
|
+
items:
|
|
5993
|
+
$ref: '#/components/schemas/PresignedUrlPart'
|
|
5994
|
+
|
|
5995
|
+
MultipartPresignSuccessEnvelope:
|
|
5996
|
+
type: object
|
|
5997
|
+
required:
|
|
5998
|
+
- success
|
|
5999
|
+
- data
|
|
6000
|
+
properties:
|
|
6001
|
+
success:
|
|
6002
|
+
type: boolean
|
|
6003
|
+
enum: [true]
|
|
6004
|
+
data:
|
|
6005
|
+
$ref: '#/components/schemas/MultipartPresignResponse'
|
|
6006
|
+
|
|
6007
|
+
MultipartKeepaliveResponse:
|
|
6008
|
+
type: object
|
|
6009
|
+
description: |
|
|
6010
|
+
Refreshed manifest TTL for an in-flight multipart session. The
|
|
6011
|
+
`data` payload on `POST /api/uploads/multipart/{uploadId}/keepalive`.
|
|
6012
|
+
required:
|
|
6013
|
+
- upload_id
|
|
6014
|
+
- manifest_expires_at
|
|
6015
|
+
properties:
|
|
6016
|
+
upload_id:
|
|
6017
|
+
$ref: '#/components/schemas/UuidV7'
|
|
6018
|
+
description: Session identifier (echoes the path `uploadId`).
|
|
6019
|
+
manifest_expires_at:
|
|
6020
|
+
type: string
|
|
6021
|
+
format: date-time
|
|
6022
|
+
description: |
|
|
6023
|
+
ISO-8601 expiry timestamp of the refreshed manifest. Always
|
|
6024
|
+
non-null on a successful 200 response — keepalive
|
|
6025
|
+
unconditionally extends the TTL to 48 h ahead of `now`.
|
|
6026
|
+
|
|
6027
|
+
MultipartKeepaliveSuccessEnvelope:
|
|
6028
|
+
type: object
|
|
6029
|
+
required:
|
|
6030
|
+
- success
|
|
6031
|
+
- data
|
|
6032
|
+
properties:
|
|
6033
|
+
success:
|
|
6034
|
+
type: boolean
|
|
6035
|
+
enum: [true]
|
|
6036
|
+
data:
|
|
6037
|
+
$ref: '#/components/schemas/MultipartKeepaliveResponse'
|
|
6038
|
+
|
|
4943
6039
|
# ============================================
|
|
4944
6040
|
# METADATA SCHEMAS
|
|
4945
6041
|
# ============================================
|
|
@@ -5231,10 +6327,21 @@ components:
|
|
|
5231
6327
|
type: array
|
|
5232
6328
|
description: |
|
|
5233
6329
|
Multi-input list for `merge`, `archive`, `image_watermark`,
|
|
5234
|
-
`custom_luma`, and `
|
|
5235
|
-
`JobInputV2` with its own `WorkflowSource`.
|
|
5236
|
-
exclusive with `source
|
|
5237
|
-
|
|
6330
|
+
`custom_luma`, `audio_overlay`, and `audio_to_video`. Each
|
|
6331
|
+
entry is a `JobInputV2` with its own `WorkflowSource`.
|
|
6332
|
+
Mutually exclusive with `source` — the V2 shape boundary
|
|
6333
|
+
stays `source` (single-input) XOR `inputs[]` (multi-input
|
|
6334
|
+
role-based) per ADR-0004 / I12.
|
|
6335
|
+
|
|
6336
|
+
**Minimum input count = sum of role minima** declared in
|
|
6337
|
+
the operation's `per_role_cardinality` (per ticket
|
|
6338
|
+
[`SlluxMBN`](https://trello.com/c/SlluxMBN) ADR-0015).
|
|
6339
|
+
`audio_to_video` requires 1 input (`base` audio; `overlay`
|
|
6340
|
+
optional, 0..1); all other role-based ops require 2+ today.
|
|
6341
|
+
The schema floor here is `minItems: 1` to admit the
|
|
6342
|
+
audio_to_video case; per-operation gates enforce the
|
|
6343
|
+
actual count via `OperationSchemaDefinition.min_inputs`.
|
|
6344
|
+
minItems: 1
|
|
5238
6345
|
items:
|
|
5239
6346
|
$ref: '#/components/schemas/JobInputV2'
|
|
5240
6347
|
operations:
|
|
@@ -5246,8 +6353,8 @@ components:
|
|
|
5246
6353
|
|
|
5247
6354
|
Multi-input jobs (with `inputs[]`) must have exactly one
|
|
5248
6355
|
operation, and it must be a multi-input type (`merge`,
|
|
5249
|
-
`archive`, `image_watermark`, `custom_luma`,
|
|
5250
|
-
`audio_overlay`).
|
|
6356
|
+
`archive`, `image_watermark`, `custom_luma`,
|
|
6357
|
+
`audio_overlay`, or `audio_to_video`).
|
|
5251
6358
|
items:
|
|
5252
6359
|
$ref: '#/components/schemas/OperationDefinition'
|
|
5253
6360
|
deliver:
|
|
@@ -5278,7 +6385,7 @@ components:
|
|
|
5278
6385
|
items:
|
|
5279
6386
|
properties:
|
|
5280
6387
|
type:
|
|
5281
|
-
enum: [merge, archive, image_watermark, custom_luma, audio_overlay]
|
|
6388
|
+
enum: [merge, archive, image_watermark, custom_luma, audio_overlay, audio_to_video, video_watermark]
|
|
5282
6389
|
required: [operations]
|
|
5283
6390
|
description: |
|
|
5284
6391
|
Multi-input jobs must have exactly one operation, and it
|
|
@@ -5325,6 +6432,21 @@ components:
|
|
|
5325
6432
|
`overlay` value already declared for `image_watermark`
|
|
5326
6433
|
— semantics differ by operation type, but the same
|
|
5327
6434
|
role label keeps the enum compact.
|
|
6435
|
+
- `audio_to_video`: REQUIRED `base` (audio source); OPTIONAL
|
|
6436
|
+
`overlay` (still image, 0..1). FIRST role-based op with
|
|
6437
|
+
an OPTIONAL role — see `per_role_cardinality` for the
|
|
6438
|
+
machine-readable cardinality declaration (per ticket
|
|
6439
|
+
[`SlluxMBN`](https://trello.com/c/SlluxMBN) /
|
|
6440
|
+
ADR-0015). Reuses `base` + `overlay` role values
|
|
6441
|
+
already declared for `image_watermark` / `audio_overlay`.
|
|
6442
|
+
- `video_watermark`: REQUIRED; values `base` (the source
|
|
6443
|
+
video) or `overlay` (the watermark image). Exactly one
|
|
6444
|
+
of each per job — `per_role_cardinality { base: 1/1,
|
|
6445
|
+
overlay: 1/1 }`. First non-introductory adoption of the
|
|
6446
|
+
`per_role_cardinality` vocab (per ticket
|
|
6447
|
+
[`4NrRPCgh`](https://trello.com/c/4NrRPCgh) /
|
|
6448
|
+
ADR-0013). `video_text_watermark` is single-input (no
|
|
6449
|
+
`role` field — text comes from options).
|
|
5328
6450
|
- `merge` / `archive`: omit (all inputs share the same role).
|
|
5329
6451
|
|
|
5330
6452
|
`text_watermark` is single-input via `JobDefinition.source`
|
|
@@ -5956,7 +7078,9 @@ components:
|
|
|
5956
7078
|
UploadProbeResponse:
|
|
5957
7079
|
type: object
|
|
5958
7080
|
description: |
|
|
5959
|
-
|
|
7081
|
+
Payload schema carried on the `data` field of
|
|
7082
|
+
`UploadProbeSuccessEnvelope` returned by
|
|
7083
|
+
`POST /api/uploads/{id}/probe`, per ticket
|
|
5960
7084
|
[I28 `KbVAnGCm`](https://trello.com/c/KbVAnGCm). Designed
|
|
5961
7085
|
so SDKs can compile a `client.preflight_clips([file_ids])`
|
|
5962
7086
|
helper into N parallel probes and aggregate by
|
|
@@ -5977,6 +7101,29 @@ components:
|
|
|
5977
7101
|
processing_class_pre_assignment:
|
|
5978
7102
|
$ref: '#/components/schemas/UploadProbeProcessingClass'
|
|
5979
7103
|
|
|
7104
|
+
UploadProbeSuccessEnvelope:
|
|
7105
|
+
type: object
|
|
7106
|
+
description: |
|
|
7107
|
+
Success envelope wrapping `UploadProbeResponse` on
|
|
7108
|
+
`POST /api/uploads/{id}/probe` 200 responses, per ticket
|
|
7109
|
+
[`9XlWEnZU`](https://trello.com/c/9XlWEnZU). Mirrors the
|
|
7110
|
+
spec-wide `*SuccessEnvelope` convention (`{success: true,
|
|
7111
|
+
data: <payload>}`) used by every other 2xx endpoint; the
|
|
7112
|
+
probe endpoint shipped during the v2.3 declared-but-pending
|
|
7113
|
+
phase missing the wrap. The API
|
|
7114
|
+
(`ApiResponseTrait::respondSuccess` in `compression_api`)
|
|
7115
|
+
already emits this shape — the envelope brings the contract
|
|
7116
|
+
in line with the wire.
|
|
7117
|
+
required:
|
|
7118
|
+
- success
|
|
7119
|
+
- data
|
|
7120
|
+
properties:
|
|
7121
|
+
success:
|
|
7122
|
+
type: boolean
|
|
7123
|
+
enum: [true]
|
|
7124
|
+
data:
|
|
7125
|
+
$ref: '#/components/schemas/UploadProbeResponse'
|
|
7126
|
+
|
|
5980
7127
|
# ============================================
|
|
5981
7128
|
# UPLOAD-SIDE GATING (per ticket I15-CONS F8.1)
|
|
5982
7129
|
# ============================================
|
|
@@ -6293,6 +7440,21 @@ components:
|
|
|
6293
7440
|
description: Progress percentage (0-100). Present when in_progress or completed.
|
|
6294
7441
|
result:
|
|
6295
7442
|
$ref: '#/components/schemas/OperationResult'
|
|
7443
|
+
error_code:
|
|
7444
|
+
type: string
|
|
7445
|
+
description: |
|
|
7446
|
+
Machine-readable failure code. Present when `status` is `failed`;
|
|
7447
|
+
absent otherwise. Mirrors `SseOperationFailedData.error_code` — the
|
|
7448
|
+
same diagnostic the SSE `operation.failed` event carries, surfaced
|
|
7449
|
+
here for polling consumers. Plain string (consumers duck-type on
|
|
7450
|
+
it), e.g. `output_too_large`.
|
|
7451
|
+
example: "output_too_large"
|
|
7452
|
+
error_message:
|
|
7453
|
+
type: string
|
|
7454
|
+
description: |
|
|
7455
|
+
Human-readable failure detail. Present when `status` is `failed`;
|
|
7456
|
+
absent otherwise. Mirrors `SseOperationFailedData.error_message`.
|
|
7457
|
+
example: "output_too_large: Output (12156489 bytes) is not smaller than input (6187609 bytes)"
|
|
6296
7458
|
|
|
6297
7459
|
OperationResult:
|
|
6298
7460
|
type: object
|
|
@@ -6370,12 +7532,37 @@ components:
|
|
|
6370
7532
|
|
|
6371
7533
|
OperationDownload:
|
|
6372
7534
|
type: object
|
|
7535
|
+
description: |
|
|
7536
|
+
A single deliverable output file for an operation. For multi-output
|
|
7537
|
+
fan-out (e.g. convert PDF->image emits one file per page), each entry
|
|
7538
|
+
carries an indexing field. This is the REST projection of the same
|
|
7539
|
+
indexing model the AsyncAPI `OperationResultOutputEntry` defines per
|
|
7540
|
+
ADR-0009 §D2 — `page_index` for PDF-page outputs, `position` for
|
|
7541
|
+
generic ordinals, mutually exclusive within an entry.
|
|
6373
7542
|
required:
|
|
6374
7543
|
- operation
|
|
6375
7544
|
- operation_id
|
|
6376
7545
|
- filename
|
|
6377
7546
|
- size_bytes
|
|
6378
7547
|
- download_url
|
|
7548
|
+
oneOf:
|
|
7549
|
+
- title: PageIndexed
|
|
7550
|
+
description: PDF-page output (convert PDF->image).
|
|
7551
|
+
required: [page_index]
|
|
7552
|
+
not: { required: [position] }
|
|
7553
|
+
- title: PositionIndexed
|
|
7554
|
+
description: Generic ordinal output (frame strip, chapter split).
|
|
7555
|
+
required: [position]
|
|
7556
|
+
not: { required: [page_index] }
|
|
7557
|
+
- title: Unindexed
|
|
7558
|
+
description: |
|
|
7559
|
+
Output without an explicit indexing field — every legacy
|
|
7560
|
+
single-output download. Schema-valid; emitted by all
|
|
7561
|
+
non-fan-out operations.
|
|
7562
|
+
not:
|
|
7563
|
+
anyOf:
|
|
7564
|
+
- required: [page_index]
|
|
7565
|
+
- required: [position]
|
|
6379
7566
|
properties:
|
|
6380
7567
|
operation:
|
|
6381
7568
|
type: string
|
|
@@ -6394,6 +7581,26 @@ components:
|
|
|
6394
7581
|
type: string
|
|
6395
7582
|
format: uri
|
|
6396
7583
|
description: Pre-signed download URL
|
|
7584
|
+
page_index:
|
|
7585
|
+
type: integer
|
|
7586
|
+
minimum: 1
|
|
7587
|
+
description: |
|
|
7588
|
+
1-based page number for PDF-page fan-out outputs (convert
|
|
7589
|
+
PDF->image). Gapless within an operation (an N-page conversion
|
|
7590
|
+
emits `page_index` 1..N). Mutually exclusive with `position`.
|
|
7591
|
+
Absent on non-indexed (single-output) downloads. Mirrors
|
|
7592
|
+
`OperationResultOutputEntry.page_index`. Per ADR-0009 §D2.
|
|
7593
|
+
example: 1
|
|
7594
|
+
position:
|
|
7595
|
+
type: integer
|
|
7596
|
+
minimum: 0
|
|
7597
|
+
description: |
|
|
7598
|
+
0-based ordinal for non-PDF multi-output operations (e.g. frame
|
|
7599
|
+
strip, chapter split). Mutually exclusive with `page_index`.
|
|
7600
|
+
Absent on non-indexed downloads. Forward-looking — not emitted by
|
|
7601
|
+
any current operation; declared for parity with
|
|
7602
|
+
`OperationResultOutputEntry.position`. Per ADR-0009 §D2.
|
|
7603
|
+
example: 0
|
|
6397
7604
|
|
|
6398
7605
|
# ============================================
|
|
6399
7606
|
# SSE EVENT SCHEMAS
|
|
@@ -6508,7 +7715,207 @@ components:
|
|
|
6508
7715
|
type: integer
|
|
6509
7716
|
const: 100
|
|
6510
7717
|
result:
|
|
6511
|
-
$ref: '#/components/schemas/
|
|
7718
|
+
$ref: '#/components/schemas/SseOperationCompletionResult'
|
|
7719
|
+
|
|
7720
|
+
SseOperationCompletionResult:
|
|
7721
|
+
description: |
|
|
7722
|
+
Result payload carried on the SSE `operation.completed` event
|
|
7723
|
+
(`SseOperationCompletedData.result`). A 2-branch `oneOf` mirroring the
|
|
7724
|
+
single-output vs multi-output completion split of the AsyncAPI
|
|
7725
|
+
`OperationResult` union (per [ADR-0009](../docs/decisions/0009-multi-output-result-envelope.md)),
|
|
7726
|
+
projected into the client-facing (download-URL) shape rather than the
|
|
7727
|
+
S3-wire shape.
|
|
7728
|
+
|
|
7729
|
+
- **Single-output**: `SseSingleOutputCompletion` (allOf wrap of
|
|
7730
|
+
`OperationResult` + a `result_kind: "single"` discriminator field).
|
|
7731
|
+
`download_url` + `size_bytes`, optional `export_key` / `metrics`. Every
|
|
7732
|
+
operation that produces one canonical output.
|
|
7733
|
+
- **Multi-output**: `SseMultiOutputCompletionWithKind` (allOf wrap of
|
|
7734
|
+
`SseMultiOutputCompletion` + a `result_kind: "multi"` discriminator
|
|
7735
|
+
field). `outputs[]` + `total_output_size_bytes`. Used by convert
|
|
7736
|
+
PDF->image and future fan-out operations.
|
|
7737
|
+
|
|
7738
|
+
Failure is **not** a branch here — it is carried by the separate
|
|
7739
|
+
`operation.failed` event (`SseOperationFailedData`), unlike the AsyncAPI
|
|
7740
|
+
`OperationResult` which folds failure into the same union.
|
|
7741
|
+
|
|
7742
|
+
**Branch dispatch via `result_kind` discriminator.** The branches are
|
|
7743
|
+
disambiguated by an explicit `result_kind` field (`"single"` |
|
|
7744
|
+
`"multi"`) that the API SSE emitter populates. The wrapper allOf shape
|
|
7745
|
+
keeps the underlying `OperationResult` and `SseMultiOutputCompletion`
|
|
7746
|
+
schemas unchanged (they continue to be used elsewhere — REST polling,
|
|
7747
|
+
AsyncAPI Lambda→API — without the discriminator). The discriminator
|
|
7748
|
+
approach replaces the v2.15.1 bare-`$ref` design, which dispatched
|
|
7749
|
+
correctly at validation but generated TS deserialization code that
|
|
7750
|
+
checked camelCase property names against snake_case wire payloads —
|
|
7751
|
+
silent data-loss on every single-output completion. The
|
|
7752
|
+
discriminator-based dispatch reads the snake_case wire key directly
|
|
7753
|
+
(`switch (json['result_kind'])`), avoiding the case-mismatch bug
|
|
7754
|
+
entirely.
|
|
7755
|
+
oneOf:
|
|
7756
|
+
- $ref: '#/components/schemas/SseSingleOutputCompletion'
|
|
7757
|
+
- $ref: '#/components/schemas/SseMultiOutputCompletionWithKind'
|
|
7758
|
+
discriminator:
|
|
7759
|
+
propertyName: result_kind
|
|
7760
|
+
mapping:
|
|
7761
|
+
single: '#/components/schemas/SseSingleOutputCompletion'
|
|
7762
|
+
multi: '#/components/schemas/SseMultiOutputCompletionWithKind'
|
|
7763
|
+
|
|
7764
|
+
SseSingleOutputCompletion:
|
|
7765
|
+
description: |
|
|
7766
|
+
Single-output branch of `SseOperationCompletionResult` — wraps
|
|
7767
|
+
`OperationResult` with a `result_kind: "single"` discriminator field
|
|
7768
|
+
so the openapi-generator dispatch can route by wire-format key
|
|
7769
|
+
(`result_kind`) rather than by structural property presence.
|
|
7770
|
+
See `SseOperationCompletionResult` description for the rationale.
|
|
7771
|
+
allOf:
|
|
7772
|
+
- $ref: '#/components/schemas/OperationResult'
|
|
7773
|
+
- type: object
|
|
7774
|
+
required:
|
|
7775
|
+
- result_kind
|
|
7776
|
+
properties:
|
|
7777
|
+
result_kind:
|
|
7778
|
+
type: string
|
|
7779
|
+
enum: [single]
|
|
7780
|
+
description: |
|
|
7781
|
+
Discriminator. Always the literal `"single"` for this branch.
|
|
7782
|
+
Emitted by the API SSE serializer; consumed by
|
|
7783
|
+
`SseOperationCompletionResult` dispatch.
|
|
7784
|
+
|
|
7785
|
+
SseMultiOutputCompletionWithKind:
|
|
7786
|
+
description: |
|
|
7787
|
+
Multi-output branch of `SseOperationCompletionResult` — wraps
|
|
7788
|
+
`SseMultiOutputCompletion` with a `result_kind: "multi"` discriminator
|
|
7789
|
+
field. See `SseOperationCompletionResult` description for the
|
|
7790
|
+
rationale.
|
|
7791
|
+
allOf:
|
|
7792
|
+
- $ref: '#/components/schemas/SseMultiOutputCompletion'
|
|
7793
|
+
- type: object
|
|
7794
|
+
required:
|
|
7795
|
+
- result_kind
|
|
7796
|
+
properties:
|
|
7797
|
+
result_kind:
|
|
7798
|
+
type: string
|
|
7799
|
+
enum: [multi]
|
|
7800
|
+
description: |
|
|
7801
|
+
Discriminator. Always the literal `"multi"` for this branch.
|
|
7802
|
+
Emitted by the API SSE serializer; consumed by
|
|
7803
|
+
`SseOperationCompletionResult` dispatch.
|
|
7804
|
+
|
|
7805
|
+
SseMultiOutputCompletion:
|
|
7806
|
+
type: object
|
|
7807
|
+
description: |
|
|
7808
|
+
Multi-output completion body for the SSE `operation.completed` event.
|
|
7809
|
+
Per-output details plus an aggregate size, mirroring the AsyncAPI
|
|
7810
|
+
`MultiOutputCompletion` branch of `OperationResult` (per
|
|
7811
|
+
[ADR-0009](../docs/decisions/0009-multi-output-result-envelope.md)) in
|
|
7812
|
+
the client-facing (download-URL) projection.
|
|
7813
|
+
required:
|
|
7814
|
+
- outputs
|
|
7815
|
+
- total_output_size_bytes
|
|
7816
|
+
properties:
|
|
7817
|
+
outputs:
|
|
7818
|
+
type: array
|
|
7819
|
+
minItems: 1
|
|
7820
|
+
maxItems: 200
|
|
7821
|
+
description: |
|
|
7822
|
+
Per-output deliverables for a multi-output operation (e.g. convert
|
|
7823
|
+
PDF->image emits one entry per page). Consumers use `outputs.length`
|
|
7824
|
+
for the count — per ADR-0009 §D4 a denormalised `output_count` was
|
|
7825
|
+
deliberately rejected. `maxItems: 200` mirrors the AsyncAPI
|
|
7826
|
+
`OperationResult.outputs` transport bound.
|
|
7827
|
+
items:
|
|
7828
|
+
$ref: '#/components/schemas/SseMultiOutputResultEntry'
|
|
7829
|
+
total_output_size_bytes:
|
|
7830
|
+
type: integer
|
|
7831
|
+
format: int64
|
|
7832
|
+
minimum: 0
|
|
7833
|
+
description: |
|
|
7834
|
+
Aggregate size of all `outputs[]` in bytes. Equals
|
|
7835
|
+
`sum(outputs[].size_bytes)`. Per ADR-0009 §D4 this is denormalised
|
|
7836
|
+
against the per-entry sum; consumers SHOULD trust the per-entry sum
|
|
7837
|
+
if the two disagree (and log a warning).
|
|
7838
|
+
example: 786432
|
|
7839
|
+
metrics:
|
|
7840
|
+
type: object
|
|
7841
|
+
description: Operation-specific performance metrics (aggregate)
|
|
7842
|
+
properties:
|
|
7843
|
+
compression_ratio:
|
|
7844
|
+
type: number
|
|
7845
|
+
format: double
|
|
7846
|
+
description: Ratio of output size to input size (e.g. 0.45 = 55% reduction)
|
|
7847
|
+
duration_ms:
|
|
7848
|
+
type: integer
|
|
7849
|
+
description: Processing time in milliseconds
|
|
7850
|
+
|
|
7851
|
+
SseMultiOutputResultEntry:
|
|
7852
|
+
type: object
|
|
7853
|
+
description: |
|
|
7854
|
+
A single deliverable output file in an SSE multi-output
|
|
7855
|
+
`operation.completed` result (`SseMultiOutputCompletion.outputs[]`).
|
|
7856
|
+
This is the SSE-local, client-facing twin of the AsyncAPI
|
|
7857
|
+
`OperationResultOutputEntry` (which is S3-wire: `output_key`) and is
|
|
7858
|
+
deliberately **decoupled** from the REST `OperationDownload` schema — it
|
|
7859
|
+
carries `download_url` + `size_bytes` and the same `page_index` /
|
|
7860
|
+
`position` indexing model defined per
|
|
7861
|
+
[ADR-0009](../docs/decisions/0009-multi-output-result-envelope.md) §D2
|
|
7862
|
+
(`page_index` for PDF-page outputs, `position` for generic ordinals,
|
|
7863
|
+
mutually exclusive within an entry).
|
|
7864
|
+
required:
|
|
7865
|
+
- download_url
|
|
7866
|
+
- size_bytes
|
|
7867
|
+
oneOf:
|
|
7868
|
+
- title: PageIndexed
|
|
7869
|
+
description: PDF-page output (convert PDF->image).
|
|
7870
|
+
required: [page_index]
|
|
7871
|
+
not: { required: [position] }
|
|
7872
|
+
- title: PositionIndexed
|
|
7873
|
+
description: Generic ordinal output (frame strip, chapter split).
|
|
7874
|
+
required: [position]
|
|
7875
|
+
not: { required: [page_index] }
|
|
7876
|
+
- title: Unindexed
|
|
7877
|
+
description: |
|
|
7878
|
+
Output without an explicit indexing field. Reserved for future
|
|
7879
|
+
operations that index by something other than page/position.
|
|
7880
|
+
Schema-valid but not currently emitted by any operation.
|
|
7881
|
+
not:
|
|
7882
|
+
anyOf:
|
|
7883
|
+
- required: [page_index]
|
|
7884
|
+
- required: [position]
|
|
7885
|
+
properties:
|
|
7886
|
+
download_url:
|
|
7887
|
+
type: string
|
|
7888
|
+
format: uri
|
|
7889
|
+
description: Pre-signed download URL for this individual output file.
|
|
7890
|
+
size_bytes:
|
|
7891
|
+
type: integer
|
|
7892
|
+
format: int64
|
|
7893
|
+
minimum: 0
|
|
7894
|
+
description: |
|
|
7895
|
+
Size of this individual output file in bytes. `minimum: 0` mirrors
|
|
7896
|
+
the AsyncAPI `OperationResultOutputEntry.output_size_bytes` bound and
|
|
7897
|
+
keeps `total_output_size_bytes` (the sum of these) internally
|
|
7898
|
+
consistent.
|
|
7899
|
+
page_index:
|
|
7900
|
+
type: integer
|
|
7901
|
+
minimum: 1
|
|
7902
|
+
description: |
|
|
7903
|
+
1-based page number for PDF-page fan-out outputs (convert
|
|
7904
|
+
PDF->image). Gapless within an operation (an N-page conversion
|
|
7905
|
+
emits `page_index` 1..N). Mutually exclusive with `position`.
|
|
7906
|
+
Absent on non-indexed outputs. Mirrors
|
|
7907
|
+
`OperationResultOutputEntry.page_index`. Per ADR-0009 §D2.
|
|
7908
|
+
example: 1
|
|
7909
|
+
position:
|
|
7910
|
+
type: integer
|
|
7911
|
+
minimum: 0
|
|
7912
|
+
description: |
|
|
7913
|
+
0-based ordinal for non-PDF multi-output operations (e.g. frame
|
|
7914
|
+
strip, chapter split). Mutually exclusive with `page_index`.
|
|
7915
|
+
Absent on non-indexed outputs. Forward-looking — not emitted by any
|
|
7916
|
+
current operation; declared for parity with
|
|
7917
|
+
`OperationResultOutputEntry.position`. Per ADR-0009 §D2.
|
|
7918
|
+
example: 0
|
|
6512
7919
|
|
|
6513
7920
|
SseOperationFailedData:
|
|
6514
7921
|
type: object
|
|
@@ -6755,11 +8162,26 @@ components:
|
|
|
6755
8162
|
$ref: '#/components/schemas/OperationInputModel'
|
|
6756
8163
|
min_inputs:
|
|
6757
8164
|
type: integer
|
|
6758
|
-
description:
|
|
6759
|
-
|
|
8165
|
+
description: |
|
|
8166
|
+
Minimum number of inputs (multi-input operations only).
|
|
8167
|
+
`audio_to_video` declares `min_inputs: 1` (first
|
|
8168
|
+
role-based op with an optional role); all other
|
|
8169
|
+
role-based ops declare `min_inputs: 2`. Per
|
|
8170
|
+
`per_role_cardinality` semantics (ADR-0015), this value
|
|
8171
|
+
equals the sum of role-level minima.
|
|
8172
|
+
minimum: 1
|
|
6760
8173
|
max_inputs:
|
|
6761
8174
|
type: integer
|
|
6762
8175
|
description: Maximum number of inputs (multi-input operations only)
|
|
8176
|
+
per_role_cardinality:
|
|
8177
|
+
$ref: '#/components/schemas/PerRoleCardinality'
|
|
8178
|
+
description: |
|
|
8179
|
+
Optional per-role input-count overlay for role-based
|
|
8180
|
+
multi-input operations. Per ticket
|
|
8181
|
+
[`SlluxMBN`](https://trello.com/c/SlluxMBN) / ADR-0015.
|
|
8182
|
+
Absent on operations whose role rules are still encoded
|
|
8183
|
+
in prose only (image_watermark, audio_overlay,
|
|
8184
|
+
custom_luma — per-op migration follow-ups).
|
|
6763
8185
|
accepts_mixed_types:
|
|
6764
8186
|
type: boolean
|
|
6765
8187
|
description: Whether mixed MIME types are allowed (archive only)
|