@giveitsmaller/contracts 0.3.0 → 0.4.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.
Files changed (331) hide show
  1. package/availability/availability.json +69 -23
  2. package/dist/openapi/models/AudioWatermarkDecodeRequest.d.ts +1 -1
  3. package/dist/openapi/models/AudioWatermarkDecodeRequest.js +1 -1
  4. package/dist/openapi/models/AudioWatermarkDecodeResponse.d.ts +1 -1
  5. package/dist/openapi/models/AudioWatermarkDecodeResponse.js +1 -1
  6. package/dist/openapi/models/AuthErrorResponse.d.ts +20 -1
  7. package/dist/openapi/models/AuthErrorResponse.js +1 -1
  8. package/dist/openapi/models/AuthErrorType.d.ts +1 -1
  9. package/dist/openapi/models/AuthErrorType.js +1 -1
  10. package/dist/openapi/models/AvailabilityValue.d.ts +1 -1
  11. package/dist/openapi/models/AvailabilityValue.js +1 -1
  12. package/dist/openapi/models/BalanceExhaustedResponse.d.ts +20 -1
  13. package/dist/openapi/models/BalanceExhaustedResponse.js +1 -1
  14. package/dist/openapi/models/BalanceExhaustedResponseAllOfLinks.d.ts +1 -1
  15. package/dist/openapi/models/BalanceExhaustedResponseAllOfLinks.js +1 -1
  16. package/dist/openapi/models/CallbackEventType.d.ts +1 -1
  17. package/dist/openapi/models/CallbackEventType.js +1 -1
  18. package/dist/openapi/models/ConnectionSource.d.ts +1 -1
  19. package/dist/openapi/models/ConnectionSource.js +1 -1
  20. package/dist/openapi/models/ContactRequest.d.ts +1 -1
  21. package/dist/openapi/models/ContactRequest.js +1 -1
  22. package/dist/openapi/models/ContactSubject.d.ts +1 -1
  23. package/dist/openapi/models/ContactSubject.js +1 -1
  24. package/dist/openapi/models/ContactValidationErrorResponse.d.ts +1 -1
  25. package/dist/openapi/models/ContactValidationErrorResponse.js +1 -1
  26. package/dist/openapi/models/CreateExternalImport403Response.d.ts +1 -1
  27. package/dist/openapi/models/CreateExternalImport403Response.js +1 -1
  28. package/dist/openapi/models/CreateExternalImport422Response.d.ts +23 -0
  29. package/dist/openapi/models/CreateExternalImport422Response.js +51 -0
  30. package/dist/openapi/models/CreateWorkflow422Response.d.ts +3 -2
  31. package/dist/openapi/models/CreateWorkflow422Response.js +8 -1
  32. package/dist/openapi/models/CreditTransaction.d.ts +1 -1
  33. package/dist/openapi/models/CreditTransaction.js +1 -1
  34. package/dist/openapi/models/CreditTransactionSourceBucket.d.ts +1 -1
  35. package/dist/openapi/models/CreditTransactionSourceBucket.js +1 -1
  36. package/dist/openapi/models/CreditsBalanceResponse.d.ts +1 -1
  37. package/dist/openapi/models/CreditsBalanceResponse.js +1 -1
  38. package/dist/openapi/models/CreditsBalanceSuccessEnvelope.d.ts +1 -1
  39. package/dist/openapi/models/CreditsBalanceSuccessEnvelope.js +1 -1
  40. package/dist/openapi/models/CreditsUsageResponse.d.ts +1 -1
  41. package/dist/openapi/models/CreditsUsageResponse.js +1 -1
  42. package/dist/openapi/models/CreditsUsageSuccessEnvelope.d.ts +1 -1
  43. package/dist/openapi/models/CreditsUsageSuccessEnvelope.js +1 -1
  44. package/dist/openapi/models/Delivery.d.ts +1 -1
  45. package/dist/openapi/models/Delivery.js +1 -1
  46. package/dist/openapi/models/DeliveryOutputRef.d.ts +1 -1
  47. package/dist/openapi/models/DeliveryOutputRef.js +1 -1
  48. package/dist/openapi/models/DeliveryPlan.d.ts +1 -1
  49. package/dist/openapi/models/DeliveryPlan.js +1 -1
  50. package/dist/openapi/models/DeliveryPlanOutput.d.ts +1 -1
  51. package/dist/openapi/models/DeliveryPlanOutput.js +1 -1
  52. package/dist/openapi/models/DeliveryPlanReason.d.ts +1 -1
  53. package/dist/openapi/models/DeliveryPlanReason.js +1 -1
  54. package/dist/openapi/models/DeliverySelection.d.ts +1 -1
  55. package/dist/openapi/models/DeliverySelection.js +1 -1
  56. package/dist/openapi/models/ErrorEnvelope.d.ts +20 -1
  57. package/dist/openapi/models/ErrorEnvelope.js +1 -1
  58. package/dist/openapi/models/EstimateQuality.d.ts +1 -1
  59. package/dist/openapi/models/EstimateQuality.js +1 -1
  60. package/dist/openapi/models/EstimateRange.d.ts +1 -1
  61. package/dist/openapi/models/EstimateRange.js +1 -1
  62. package/dist/openapi/models/ExternalDestination.d.ts +1 -1
  63. package/dist/openapi/models/ExternalDestination.js +1 -1
  64. package/dist/openapi/models/ExternalImportCreatedResponse.d.ts +1 -1
  65. package/dist/openapi/models/ExternalImportCreatedResponse.js +1 -1
  66. package/dist/openapi/models/ExternalImportCreatedSuccessEnvelope.d.ts +1 -1
  67. package/dist/openapi/models/ExternalImportCreatedSuccessEnvelope.js +1 -1
  68. package/dist/openapi/models/ExternalImportRequest.d.ts +1 -1
  69. package/dist/openapi/models/ExternalImportRequest.js +1 -1
  70. package/dist/openapi/models/ExternalImportToken.d.ts +1 -1
  71. package/dist/openapi/models/ExternalImportToken.js +1 -1
  72. package/dist/openapi/models/ExternalSource.d.ts +1 -1
  73. package/dist/openapi/models/ExternalSource.js +1 -1
  74. package/dist/openapi/models/FeatureNotAvailableResponse.d.ts +26 -3
  75. package/dist/openapi/models/FeatureNotAvailableResponse.js +1 -1
  76. package/dist/openapi/models/FeatureTierRestrictedResponse.d.ts +20 -1
  77. package/dist/openapi/models/FeatureTierRestrictedResponse.js +1 -1
  78. package/dist/openapi/models/FeatureViolation.d.ts +1 -1
  79. package/dist/openapi/models/FeatureViolation.js +1 -1
  80. package/dist/openapi/models/JobDefinition.d.ts +1 -1
  81. package/dist/openapi/models/JobDefinition.js +1 -1
  82. package/dist/openapi/models/JobDownload.d.ts +1 -1
  83. package/dist/openapi/models/JobDownload.js +1 -1
  84. package/dist/openapi/models/JobInputV2.d.ts +1 -1
  85. package/dist/openapi/models/JobInputV2.js +1 -1
  86. package/dist/openapi/models/JobOutputSource.d.ts +1 -1
  87. package/dist/openapi/models/JobOutputSource.js +1 -1
  88. package/dist/openapi/models/JobResponse.d.ts +1 -1
  89. package/dist/openapi/models/JobResponse.js +1 -1
  90. package/dist/openapi/models/JobStatus.d.ts +1 -1
  91. package/dist/openapi/models/JobStatus.js +1 -1
  92. package/dist/openapi/models/JobType.d.ts +1 -1
  93. package/dist/openapi/models/JobType.js +1 -1
  94. package/dist/openapi/models/LivenessResponse.d.ts +1 -1
  95. package/dist/openapi/models/LivenessResponse.js +1 -1
  96. package/dist/openapi/models/LoginUser200Response.d.ts +1 -1
  97. package/dist/openapi/models/LoginUser200Response.js +1 -1
  98. package/dist/openapi/models/LoginUser200ResponseData.d.ts +1 -1
  99. package/dist/openapi/models/LoginUser200ResponseData.js +1 -1
  100. package/dist/openapi/models/LoginUser200ResponseDataUser.d.ts +1 -1
  101. package/dist/openapi/models/LoginUser200ResponseDataUser.js +1 -1
  102. package/dist/openapi/models/LoginUserRequest.d.ts +1 -1
  103. package/dist/openapi/models/LoginUserRequest.js +1 -1
  104. package/dist/openapi/models/LogoutUser200Response.d.ts +1 -1
  105. package/dist/openapi/models/LogoutUser200Response.js +1 -1
  106. package/dist/openapi/models/MetadataResponse.d.ts +1 -1
  107. package/dist/openapi/models/MetadataResponse.js +1 -1
  108. package/dist/openapi/models/MetadataResponseDimensions.d.ts +1 -1
  109. package/dist/openapi/models/MetadataResponseDimensions.js +1 -1
  110. package/dist/openapi/models/MetadataResponseExif.d.ts +1 -1
  111. package/dist/openapi/models/MetadataResponseExif.js +1 -1
  112. package/dist/openapi/models/MetadataResponseExifGps.d.ts +1 -1
  113. package/dist/openapi/models/MetadataResponseExifGps.js +1 -1
  114. package/dist/openapi/models/MetadataSuccessEnvelope.d.ts +1 -1
  115. package/dist/openapi/models/MetadataSuccessEnvelope.js +1 -1
  116. package/dist/openapi/models/MimeGroupSchema.d.ts +1 -1
  117. package/dist/openapi/models/MimeGroupSchema.js +1 -1
  118. package/dist/openapi/models/MultipartCompleteRequest.d.ts +1 -1
  119. package/dist/openapi/models/MultipartCompleteRequest.js +1 -1
  120. package/dist/openapi/models/MultipartCompleteRequestPartsInner.d.ts +1 -1
  121. package/dist/openapi/models/MultipartCompleteRequestPartsInner.js +1 -1
  122. package/dist/openapi/models/MultipartCompleteResponse.d.ts +1 -1
  123. package/dist/openapi/models/MultipartCompleteResponse.js +1 -1
  124. package/dist/openapi/models/MultipartCompleteSuccessEnvelope.d.ts +1 -1
  125. package/dist/openapi/models/MultipartCompleteSuccessEnvelope.js +1 -1
  126. package/dist/openapi/models/MultipartInitiateRequestMetadataHint.d.ts +1 -1
  127. package/dist/openapi/models/MultipartInitiateRequestMetadataHint.js +1 -1
  128. package/dist/openapi/models/MultipartInitiateResponse.d.ts +20 -4
  129. package/dist/openapi/models/MultipartInitiateResponse.js +1 -1
  130. package/dist/openapi/models/MultipartInitiateSuccessEnvelope.d.ts +1 -1
  131. package/dist/openapi/models/MultipartInitiateSuccessEnvelope.js +1 -1
  132. package/dist/openapi/models/MultipartKeepaliveResponse.d.ts +43 -0
  133. package/dist/openapi/models/MultipartKeepaliveResponse.js +47 -0
  134. package/dist/openapi/models/MultipartKeepaliveSuccessEnvelope.d.ts +46 -0
  135. package/dist/openapi/models/MultipartKeepaliveSuccessEnvelope.js +54 -0
  136. package/dist/openapi/models/MultipartPartListing.d.ts +59 -0
  137. package/dist/openapi/models/MultipartPartListing.js +55 -0
  138. package/dist/openapi/models/MultipartPresignRequest.d.ts +41 -0
  139. package/dist/openapi/models/MultipartPresignRequest.js +43 -0
  140. package/dist/openapi/models/MultipartPresignResponse.d.ts +46 -0
  141. package/dist/openapi/models/MultipartPresignResponse.js +48 -0
  142. package/dist/openapi/models/MultipartPresignSuccessEnvelope.d.ts +46 -0
  143. package/dist/openapi/models/MultipartPresignSuccessEnvelope.js +54 -0
  144. package/dist/openapi/models/MultipartStatusResponse.d.ts +103 -0
  145. package/dist/openapi/models/MultipartStatusResponse.js +76 -0
  146. package/dist/openapi/models/MultipartStatusSuccessEnvelope.d.ts +46 -0
  147. package/dist/openapi/models/MultipartStatusSuccessEnvelope.js +54 -0
  148. package/dist/openapi/models/OperationDefinition.d.ts +1 -1
  149. package/dist/openapi/models/OperationDefinition.js +1 -1
  150. package/dist/openapi/models/OperationDownload.d.ts +29 -1
  151. package/dist/openapi/models/OperationDownload.js +5 -1
  152. package/dist/openapi/models/OperationInputModel.d.ts +1 -1
  153. package/dist/openapi/models/OperationInputModel.js +1 -1
  154. package/dist/openapi/models/OperationResponse.d.ts +20 -1
  155. package/dist/openapi/models/OperationResponse.js +5 -1
  156. package/dist/openapi/models/OperationResult.d.ts +1 -1
  157. package/dist/openapi/models/OperationResult.js +1 -1
  158. package/dist/openapi/models/OperationResultMetrics.d.ts +1 -1
  159. package/dist/openapi/models/OperationResultMetrics.js +1 -1
  160. package/dist/openapi/models/OperationSchemaDefinition.d.ts +1 -1
  161. package/dist/openapi/models/OperationSchemaDefinition.js +1 -1
  162. package/dist/openapi/models/OperationStatus.d.ts +1 -1
  163. package/dist/openapi/models/OperationStatus.js +1 -1
  164. package/dist/openapi/models/OperationType.d.ts +1 -1
  165. package/dist/openapi/models/OperationType.js +1 -1
  166. package/dist/openapi/models/OperationsSchemaResponse.d.ts +1 -1
  167. package/dist/openapi/models/OperationsSchemaResponse.js +1 -1
  168. package/dist/openapi/models/OptionSchema.d.ts +1 -1
  169. package/dist/openapi/models/OptionSchema.js +1 -1
  170. package/dist/openapi/models/PerValueAvailabilityEntry.d.ts +1 -1
  171. package/dist/openapi/models/PerValueAvailabilityEntry.js +1 -1
  172. package/dist/openapi/models/PresignedUrlPart.d.ts +1 -1
  173. package/dist/openapi/models/PresignedUrlPart.js +1 -1
  174. package/dist/openapi/models/ProcessingClass.d.ts +1 -1
  175. package/dist/openapi/models/ProcessingClass.js +1 -1
  176. package/dist/openapi/models/ProcessingClassBandViolation.d.ts +149 -0
  177. package/dist/openapi/models/ProcessingClassBandViolation.js +81 -0
  178. package/dist/openapi/models/ProcessingClassExceedsBandResponse.d.ts +174 -0
  179. package/dist/openapi/models/ProcessingClassExceedsBandResponse.js +76 -0
  180. package/dist/openapi/models/ProcessingClassHint.d.ts +1 -1
  181. package/dist/openapi/models/ProcessingClassHint.js +1 -1
  182. package/dist/openapi/models/ProcessingClassReason.d.ts +1 -1
  183. package/dist/openapi/models/ProcessingClassReason.js +1 -1
  184. package/dist/openapi/models/ProcessingClassRejectReason.d.ts +53 -0
  185. package/dist/openapi/models/ProcessingClassRejectReason.js +71 -0
  186. package/dist/openapi/models/ProcessingPlan.d.ts +1 -1
  187. package/dist/openapi/models/ProcessingPlan.js +1 -1
  188. package/dist/openapi/models/ProcessingPlanJob.d.ts +1 -1
  189. package/dist/openapi/models/ProcessingPlanJob.js +1 -1
  190. package/dist/openapi/models/ReadinessResponse.d.ts +1 -1
  191. package/dist/openapi/models/ReadinessResponse.js +1 -1
  192. package/dist/openapi/models/ResponseEnvelope.d.ts +1 -1
  193. package/dist/openapi/models/ResponseEnvelope.js +1 -1
  194. package/dist/openapi/models/RetryResponse.d.ts +1 -1
  195. package/dist/openapi/models/RetryResponse.js +1 -1
  196. package/dist/openapi/models/RetrySuccessEnvelope.d.ts +1 -1
  197. package/dist/openapi/models/RetrySuccessEnvelope.js +1 -1
  198. package/dist/openapi/models/SseEventType.d.ts +1 -1
  199. package/dist/openapi/models/SseEventType.js +1 -1
  200. package/dist/openapi/models/SseJobCompletedData.d.ts +1 -1
  201. package/dist/openapi/models/SseJobCompletedData.js +1 -1
  202. package/dist/openapi/models/SseJobFailedData.d.ts +1 -1
  203. package/dist/openapi/models/SseJobFailedData.js +1 -1
  204. package/dist/openapi/models/SseOperationCompletedData.d.ts +1 -1
  205. package/dist/openapi/models/SseOperationCompletedData.js +1 -1
  206. package/dist/openapi/models/SseOperationFailedData.d.ts +1 -1
  207. package/dist/openapi/models/SseOperationFailedData.js +1 -1
  208. package/dist/openapi/models/SseOperationProgressData.d.ts +1 -1
  209. package/dist/openapi/models/SseOperationProgressData.js +1 -1
  210. package/dist/openapi/models/SseWorkflowTerminalData.d.ts +1 -1
  211. package/dist/openapi/models/SseWorkflowTerminalData.js +1 -1
  212. package/dist/openapi/models/TierRestrictionKind.d.ts +1 -1
  213. package/dist/openapi/models/TierRestrictionKind.js +1 -1
  214. package/dist/openapi/models/TierRestrictionResponse.d.ts +20 -1
  215. package/dist/openapi/models/TierRestrictionResponse.js +1 -1
  216. package/dist/openapi/models/UploadConstraintsApplied.d.ts +1 -1
  217. package/dist/openapi/models/UploadConstraintsApplied.js +1 -1
  218. package/dist/openapi/models/UploadDurationExceedsTierResponse.d.ts +20 -1
  219. package/dist/openapi/models/UploadDurationExceedsTierResponse.js +1 -1
  220. package/dist/openapi/models/UploadFile403Response.d.ts +1 -1
  221. package/dist/openapi/models/UploadFile403Response.js +1 -1
  222. package/dist/openapi/models/UploadFile422Response.d.ts +1 -1
  223. package/dist/openapi/models/UploadFile422Response.js +1 -1
  224. package/dist/openapi/models/UploadProbeMediaMetadata.d.ts +1 -1
  225. package/dist/openapi/models/UploadProbeMediaMetadata.js +1 -1
  226. package/dist/openapi/models/UploadProbeProcessingClass.d.ts +1 -1
  227. package/dist/openapi/models/UploadProbeProcessingClass.js +1 -1
  228. package/dist/openapi/models/UploadProbeResponse.d.ts +1 -1
  229. package/dist/openapi/models/UploadProbeResponse.js +1 -1
  230. package/dist/openapi/models/UploadProbeStatus.d.ts +1 -1
  231. package/dist/openapi/models/UploadProbeStatus.js +1 -1
  232. package/dist/openapi/models/UploadResponse.d.ts +1 -1
  233. package/dist/openapi/models/UploadResponse.js +1 -1
  234. package/dist/openapi/models/UploadSizeExceedsTierResponse.d.ts +20 -1
  235. package/dist/openapi/models/UploadSizeExceedsTierResponse.js +1 -1
  236. package/dist/openapi/models/UploadSource.d.ts +1 -1
  237. package/dist/openapi/models/UploadSource.js +1 -1
  238. package/dist/openapi/models/UploadSuccessEnvelope.d.ts +1 -1
  239. package/dist/openapi/models/UploadSuccessEnvelope.js +1 -1
  240. package/dist/openapi/models/UploadThresholds.d.ts +11 -4
  241. package/dist/openapi/models/UploadThresholds.js +2 -2
  242. package/dist/openapi/models/UserTier.d.ts +1 -1
  243. package/dist/openapi/models/UserTier.js +1 -1
  244. package/dist/openapi/models/ValidationErrorEnvelope.d.ts +1 -1
  245. package/dist/openapi/models/ValidationErrorEnvelope.js +1 -1
  246. package/dist/openapi/models/ValidationErrorEnvelopeDetailsInner.d.ts +1 -1
  247. package/dist/openapi/models/ValidationErrorEnvelopeDetailsInner.js +1 -1
  248. package/dist/openapi/models/WarningType.d.ts +1 -1
  249. package/dist/openapi/models/WarningType.js +1 -1
  250. package/dist/openapi/models/WebhookOperationContext.d.ts +1 -1
  251. package/dist/openapi/models/WebhookOperationContext.js +1 -1
  252. package/dist/openapi/models/WebhookPayload.d.ts +1 -1
  253. package/dist/openapi/models/WebhookPayload.js +1 -1
  254. package/dist/openapi/models/WorkflowCancelBillingEffect.d.ts +1 -1
  255. package/dist/openapi/models/WorkflowCancelBillingEffect.js +1 -1
  256. package/dist/openapi/models/WorkflowCancelResponse.d.ts +1 -1
  257. package/dist/openapi/models/WorkflowCancelResponse.js +1 -1
  258. package/dist/openapi/models/WorkflowCancelSuccessEnvelope.d.ts +1 -1
  259. package/dist/openapi/models/WorkflowCancelSuccessEnvelope.js +1 -1
  260. package/dist/openapi/models/WorkflowCreateRequest.d.ts +1 -1
  261. package/dist/openapi/models/WorkflowCreateRequest.js +1 -1
  262. package/dist/openapi/models/WorkflowCreateResponse.d.ts +1 -1
  263. package/dist/openapi/models/WorkflowCreateResponse.js +1 -1
  264. package/dist/openapi/models/WorkflowCreateSuccessEnvelope.d.ts +1 -1
  265. package/dist/openapi/models/WorkflowCreateSuccessEnvelope.js +1 -1
  266. package/dist/openapi/models/WorkflowDownloadResponse.d.ts +1 -1
  267. package/dist/openapi/models/WorkflowDownloadResponse.js +1 -1
  268. package/dist/openapi/models/WorkflowDownloadSuccessEnvelope.d.ts +1 -1
  269. package/dist/openapi/models/WorkflowDownloadSuccessEnvelope.js +1 -1
  270. package/dist/openapi/models/WorkflowEdge.d.ts +1 -1
  271. package/dist/openapi/models/WorkflowEdge.js +1 -1
  272. package/dist/openapi/models/WorkflowExpiredResponse.d.ts +20 -1
  273. package/dist/openapi/models/WorkflowExpiredResponse.js +1 -1
  274. package/dist/openapi/models/WorkflowPauseRequiredAction.d.ts +1 -1
  275. package/dist/openapi/models/WorkflowPauseRequiredAction.js +1 -1
  276. package/dist/openapi/models/WorkflowPausedDetail.d.ts +1 -1
  277. package/dist/openapi/models/WorkflowPausedDetail.js +1 -1
  278. package/dist/openapi/models/WorkflowPausedDetailLinks.d.ts +1 -1
  279. package/dist/openapi/models/WorkflowPausedDetailLinks.js +1 -1
  280. package/dist/openapi/models/WorkflowProcessing.d.ts +1 -1
  281. package/dist/openapi/models/WorkflowProcessing.js +1 -1
  282. package/dist/openapi/models/WorkflowResumeResponse.d.ts +1 -1
  283. package/dist/openapi/models/WorkflowResumeResponse.js +1 -1
  284. package/dist/openapi/models/WorkflowResumeSuccessEnvelope.d.ts +1 -1
  285. package/dist/openapi/models/WorkflowResumeSuccessEnvelope.js +1 -1
  286. package/dist/openapi/models/WorkflowSource.d.ts +1 -1
  287. package/dist/openapi/models/WorkflowSource.js +1 -1
  288. package/dist/openapi/models/WorkflowStatus.d.ts +1 -1
  289. package/dist/openapi/models/WorkflowStatus.js +1 -1
  290. package/dist/openapi/models/WorkflowStatusResponse.d.ts +1 -1
  291. package/dist/openapi/models/WorkflowStatusResponse.js +1 -1
  292. package/dist/openapi/models/WorkflowStatusSuccessEnvelope.d.ts +1 -1
  293. package/dist/openapi/models/WorkflowStatusSuccessEnvelope.js +1 -1
  294. package/dist/openapi/models/WorkflowWarning.d.ts +1 -1
  295. package/dist/openapi/models/WorkflowWarning.js +1 -1
  296. package/dist/openapi/models/WorkflowWarningSeverity.d.ts +1 -1
  297. package/dist/openapi/models/WorkflowWarningSeverity.js +1 -1
  298. package/dist/openapi/models/index.d.ts +12 -0
  299. package/dist/openapi/models/index.js +12 -0
  300. package/dist/openapi/runtime.d.ts +1 -1
  301. package/dist/openapi/runtime.js +1 -1
  302. package/dist/operations/audio_overlay.metadata.js +4 -4
  303. package/dist/operations/audio_watermark.metadata.js +4 -4
  304. package/dist/operations/compress.metadata.js +3 -3
  305. package/dist/operations/convert.metadata.js +2 -2
  306. package/dist/operations/custom_luma.metadata.js +2 -2
  307. package/dist/operations/image_watermark.metadata.js +2 -2
  308. package/dist/operations/merge.metadata.js +3 -3
  309. package/dist/operations/thumbnail.metadata.js +1 -1
  310. package/openapi/api.yaml +1008 -37
  311. package/operations/schemas/audio_overlay.yaml +18 -6
  312. package/operations/schemas/audio_watermark.yaml +14 -6
  313. package/operations/schemas/compress.yaml +10 -4
  314. package/operations/schemas/convert.yaml +10 -3
  315. package/operations/schemas/custom_luma.yaml +10 -3
  316. package/operations/schemas/image_watermark.yaml +10 -3
  317. package/operations/schemas/merge.yaml +10 -4
  318. package/operations/schemas/thumbnail.yaml +9 -2
  319. package/package.json +1 -1
  320. package/dist/asyncapi/AnonymousSchema_13.d.ts +0 -6
  321. package/dist/asyncapi/AnonymousSchema_13.js +0 -7
  322. package/dist/asyncapi/AnonymousSchema_152.d.ts +0 -5
  323. package/dist/asyncapi/AnonymousSchema_152.js +0 -6
  324. package/dist/openapi/models/ExportConfig.d.ts +0 -63
  325. package/dist/openapi/models/ExportConfig.js +0 -59
  326. package/dist/openapi/models/JobInput.d.ts +0 -53
  327. package/dist/openapi/models/JobInput.js +0 -47
  328. package/dist/openapi/models/JobSource.d.ts +0 -43
  329. package/dist/openapi/models/JobSource.js +0 -45
  330. package/dist/operations/watermark.d.ts +0 -28
  331. 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.7.1
78
+ version: 2.12.0
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` (5 MiB) with
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 5MB-100MB
315
- - The last part may be smaller than 5MB (S3 allows this for the final part)
316
- - Maximum 500 parts per upload
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: 10485760
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
@@ -762,12 +1121,21 @@ paths:
762
1121
  side-effect dependencies that don't surface as `from`
763
1122
  references).
764
1123
 
765
- **Default operation:** if `operations` is omitted on a
766
- single-input job with `source: { type: upload, ... }`, the
767
- default is `[{ "type": "compress" }]` with default options for
768
- the detected MIME type. Multi-input jobs must always specify
1124
+ **Default operation:** if `operations` is omitted or
1125
+ explicitly empty (`[]`) on a single-input job with
1126
+ `source: { type: upload, ... }`, the default is
1127
+ `[{ "type": "compress" }]` with default options for the
1128
+ detected MIME type. Multi-input jobs must always specify
769
1129
  operations explicitly.
770
1130
 
1131
+ **Compression opt-out:** V2 has no `skip_compression` flag —
1132
+ `operations[]` *is* the chain. To opt a job out of
1133
+ compression, send an explicit non-empty `operations[]` that
1134
+ does not include `compress`; on a single-input upload job an
1135
+ empty `[]` does *not* opt out (it is treated as omitted and
1136
+ still receives the implicit `compress` — see above). Per
1137
+ [ADR-0004](../docs/decisions/0004-job-shape.md).
1138
+
771
1139
  **Multi-input constraint:** multi-input jobs (`inputs[]`) must
772
1140
  have exactly one operation, which must be a multi-input type
773
1141
  (`merge`, `archive`, `image_watermark`, `custom_luma`, or
@@ -1077,7 +1445,7 @@ paths:
1077
1445
  error: "Upload not found: 019539ab-1111-7000-8000-999999999999"
1078
1446
  '422':
1079
1447
  description: |
1080
- Semantically invalid request. Either:
1448
+ Semantically invalid request. One of:
1081
1449
 
1082
1450
  - Generic validation error (unknown operation type, invalid
1083
1451
  option combinations, cyclic dependency in workflow_edges,
@@ -1090,6 +1458,22 @@ paths:
1090
1458
  with `error_type: feature_not_available`. Per ADR-0001
1091
1459
  §1.3 Tension 1 rule, the server MUST honour tagged
1092
1460
  availability.
1461
+ - Processing-class band-ceiling overflow — returned as
1462
+ `ProcessingClassExceedsBandResponse` with `error_type:
1463
+ processing_class_exceeds_band`. Fires when one or more
1464
+ jobs cannot be classified because input size/duration
1465
+ exceeds the `long_form` (or `long_form_re_encode`)
1466
+ ceiling under the caller's effective per-tier caps
1467
+ (`per_tier_constraints` overlay per
1468
+ [ADR-0011](../docs/decisions/0011-per-tier-processing-class-constraints.md)).
1469
+ Per-violation `required_tier` names the tier (if any)
1470
+ whose `per_tier_constraints` would accommodate the
1471
+ request (`null` = no tier resolves, e.g. enterprise
1472
+ already at the 120 GB hard ceiling). Distinct from
1473
+ `TierRestrictionResponse` (403, request-level upload
1474
+ quota — see [ADR-0012](../docs/decisions/0012-processing-class-band-reject-envelope.md)
1475
+ for the band-vs-tier split). Per ADR-0001 §F6
1476
+ batched-violations rule, `violations[]` is fail-all.
1093
1477
  - Re-encode required (per ticket I16-CONS, Trello
1094
1478
  `7nCZXEru`). Returned for `merge.video` jobs with
1095
1479
  `re_encode_mode: never` when the compatibility probe
@@ -1108,27 +1492,29 @@ paths:
1108
1492
  Backward-compatibility note: the prior 422 shape
1109
1493
  (`ValidationErrorEnvelope`) is preserved unchanged — its
1110
1494
  `details[]` array is the structural signature consumers
1111
- duck-type against. The new `FeatureNotAvailableResponse`
1112
- branch carries `error_type: feature_not_available` +
1113
- `violations[]` instead. The `REQUIRES_REENCODE` flavour
1114
- reuses `ValidationErrorEnvelope` (a user-fixable validation
1115
- error in the same family as `INVALID_OPTIONS`) and is
1116
- distinguished by the stable `error: "REQUIRES_REENCODE"`
1117
- string code rather than a new `error_type` enum value.
1118
- Branches are distinguishable by required fields (`details`
1119
- vs `error_type`+`violations`), so plain `oneOf` matches
1120
- without a discriminator object see `openapi/api.yaml`
1121
- §"FEATURE AVAILABILITY ENVELOPES" commentary for the
1122
- convention rationale (no discriminator here because
1123
- `ValidationErrorEnvelope` has no `error_type` field;
1124
- OpenAPI 3.1 discriminators require the property to be
1125
- present on every branch).
1495
+ duck-type against. `FeatureNotAvailableResponse` carries
1496
+ `error_type: feature_not_available` + `violations[]`;
1497
+ `ProcessingClassExceedsBandResponse` carries `error_type:
1498
+ processing_class_exceeds_band` + `violations[]`. The
1499
+ `REQUIRES_REENCODE` flavour reuses `ValidationErrorEnvelope`
1500
+ (a user-fixable validation error in the same family as
1501
+ `INVALID_OPTIONS`) and is distinguished by the stable
1502
+ `error: "REQUIRES_REENCODE"` string code rather than a new
1503
+ `error_type` enum value. Branches are distinguishable by
1504
+ required-field shape (`details` vs `error_type` value), so
1505
+ plain `oneOf` matches without a discriminator object — see
1506
+ `openapi/api.yaml` §"FEATURE AVAILABILITY ENVELOPES"
1507
+ commentary for the convention rationale (no discriminator
1508
+ here because `ValidationErrorEnvelope` has no `error_type`
1509
+ field; OpenAPI 3.1 discriminators require the property to
1510
+ be present on every branch).
1126
1511
  content:
1127
1512
  application/json:
1128
1513
  schema:
1129
1514
  oneOf:
1130
1515
  - $ref: '#/components/schemas/ValidationErrorEnvelope'
1131
1516
  - $ref: '#/components/schemas/FeatureNotAvailableResponse'
1517
+ - $ref: '#/components/schemas/ProcessingClassExceedsBandResponse'
1132
1518
  examples:
1133
1519
  validation_error:
1134
1520
  summary: Generic validation error (legacy shape)
@@ -1155,6 +1541,43 @@ paths:
1155
1541
  documentation_url: "https://docs.giveitsmaller.com/operations/audio_overlay"
1156
1542
  - feature: "operation.merge.mime_group.image.option.transition.dissolve"
1157
1543
  availability: "experimental"
1544
+ processing_class_exceeds_band_combined_size:
1545
+ summary: |
1546
+ merge job whose summed inputs (130 GB) exceed the
1547
+ Enterprise long_form_re_encode ceiling (120 GB
1548
+ hard cap per ADR-0011). Terminal — no tier
1549
+ resolves it; `required_tier` is null.
1550
+ value:
1551
+ success: false
1552
+ error: "Workflow contains inputs that exceed the long-form processing-class ceiling"
1553
+ error_type: "processing_class_exceeds_band"
1554
+ violations:
1555
+ - reason: "combined_size_exceeds_long_form"
1556
+ job_ref: "stitched"
1557
+ operation: "merge"
1558
+ processing_class: "long_form_re_encode"
1559
+ actual: 130000000000
1560
+ ceiling: 120000000000
1561
+ required_tier: null
1562
+ documentation_url: "https://docs.giveitsmaller.com/processing-class/long-form"
1563
+ processing_class_exceeds_band_single_input_duration:
1564
+ summary: |
1565
+ compress.video job whose single input duration
1566
+ (15 hours = 54000s) exceeds the Pro long_form
1567
+ `max_input_duration` (PT12H = 43200s). Upgrade to
1568
+ Enterprise resolves the duration cap.
1569
+ value:
1570
+ success: false
1571
+ error: "Workflow contains inputs that exceed the long-form processing-class ceiling"
1572
+ error_type: "processing_class_exceeds_band"
1573
+ violations:
1574
+ - reason: "input_duration_exceeds_long_form"
1575
+ job_ref: "job_0"
1576
+ operation: "compress"
1577
+ processing_class: "long_form"
1578
+ actual: 54000
1579
+ ceiling: 43200
1580
+ required_tier: "enterprise"
1158
1581
  requires_reencode:
1159
1582
  summary: merge.video re_encode_mode=never with incompatible inputs (I16-CONS)
1160
1583
  value:
@@ -2796,6 +3219,25 @@ components:
2796
3219
  `REQUIRES_REENCODE`). Canonical English; never localised.
2797
3220
  SDKs duck-type on this field for typed error-branch
2798
3221
  helpers.
3222
+
3223
+ Multipart-session resume codes (per ticket
3224
+ [`HxUmVr3Y`](https://trello.com/c/HxUmVr3Y), V2.10.0):
3225
+ - `MULTIPART_SESSION_NOT_FOUND` (404) — upload_id does
3226
+ not match an in-flight session (expired / never
3227
+ existed / wrong account namespace). Fired by /status,
3228
+ /presign, /keepalive.
3229
+ - `MULTIPART_SESSION_OWNERSHIP` (403) — authenticated
3230
+ caller is not the session owner. Fired by /status,
3231
+ /presign, /keepalive, /complete (when manifest.userId
3232
+ is non-null and differs).
3233
+ - `MULTIPART_SESSION_AUTH_REQUIRED` (403) — session was
3234
+ anonymously initiated; the three resume endpoints
3235
+ require authentication. The `8LABloaz` follow-up will
3236
+ flip `/initiate` to also require auth.
3237
+ - `FILE_TOO_LARGE_FOR_MULTIPART` (422) — assembled object
3238
+ would exceed the S3 multipart capacity cap. Pre-S3
3239
+ server-side capacity gate; distinct from tier-quota
3240
+ rejections (`upload_size_exceeds_tier`).
2799
3241
  message:
2800
3242
  type: string
2801
3243
  description: |
@@ -4274,8 +4716,12 @@ components:
4274
4716
  rejection.
4275
4717
 
4276
4718
  The 422 response is delivered alongside `ValidationErrorEnvelope`
4277
- via `oneOf + discriminator` on `error_type` — see the 422
4278
- response on `POST /api/workflows`.
4719
+ and `ProcessingClassExceedsBandResponse` via a naked `oneOf`
4720
+ (duck-typed on required-field shape — `details` vs `error_type`
4721
+ value: `feature_not_available` vs `processing_class_exceeds_band`).
4722
+ No discriminator object is used because `ValidationErrorEnvelope`
4723
+ has no `error_type` field. See the 422 response on
4724
+ `POST /api/workflows`.
4279
4725
  allOf:
4280
4726
  - $ref: '#/components/schemas/ErrorEnvelope'
4281
4727
  - type: object
@@ -4299,6 +4745,205 @@ components:
4299
4745
  items:
4300
4746
  $ref: '#/components/schemas/FeatureViolation'
4301
4747
 
4748
+ ProcessingClassRejectReason:
4749
+ type: string
4750
+ description: |
4751
+ Why a job cannot be classified — input size/duration exceeds
4752
+ the `long_form` (or `long_form_re_encode`) ceiling under the
4753
+ caller's effective per-tier caps (per
4754
+ [ADR-0011](../docs/decisions/0011-per-tier-processing-class-constraints.md)
4755
+ `per_tier_constraints`). Distinct from `ProcessingClassReason`
4756
+ (which describes WHY a job got its assigned class — success-
4757
+ path advisory).
4758
+
4759
+ Reasons are split by the violated constraint key on the
4760
+ processing-class block (per `schemas/FORMAT.md`
4761
+ §"`processing_class:` block"):
4762
+
4763
+ - `input_size_exceeds_long_form` /
4764
+ `input_duration_exceeds_long_form`: a **single input**
4765
+ exceeds the per-input ceiling (`max_input_size_bytes` /
4766
+ `max_input_duration`). Applies to single-input operations
4767
+ (compress, convert, thumbnail, text_watermark,
4768
+ audio_watermark) AND per-input checks on multi-input
4769
+ operations with per-input caps (image_watermark,
4770
+ custom_luma, audio_overlay).
4771
+ - `combined_size_exceeds_long_form` /
4772
+ `combined_duration_exceeds_long_form`: the **summed** inputs
4773
+ exceed the multi-input combined ceiling
4774
+ (`max_total_input_size_bytes` / `max_total_duration`).
4775
+ Applies to operations whose `processing_class.<class>.
4776
+ constraints` carries `max_total_*` — merge today.
4777
+ enum:
4778
+ - input_size_exceeds_long_form
4779
+ - input_duration_exceeds_long_form
4780
+ - combined_size_exceeds_long_form
4781
+ - combined_duration_exceeds_long_form
4782
+
4783
+ ProcessingClassBandViolation:
4784
+ type: object
4785
+ description: |
4786
+ One band-ceiling overflow on a workflow-create reject. Carries
4787
+ the I26 localisation quad on the violation (mirrors
4788
+ `FeatureViolation`); envelope-level localisation rides via
4789
+ `allOf [ErrorEnvelope]` on `ProcessingClassExceedsBandResponse`.
4790
+
4791
+ `job_ref`, `actual`, `ceiling`, `operation`, and
4792
+ `processing_class` are REQUIRED — the server always knows them
4793
+ at reject time and consumers rely on them to (a) correlate
4794
+ fail-all violations back to the offending job in multi-job
4795
+ workflows and (b) render "X exceeded by Y" without re-deriving
4796
+ caps from the per-tier overlay.
4797
+ required:
4798
+ - reason
4799
+ - job_ref
4800
+ - operation
4801
+ - processing_class
4802
+ - actual
4803
+ - ceiling
4804
+ properties:
4805
+ reason:
4806
+ $ref: '#/components/schemas/ProcessingClassRejectReason'
4807
+ job_ref:
4808
+ type: string
4809
+ description: |
4810
+ Workflow-local job identifier — `JobDefinition.id` if the
4811
+ caller supplied one, otherwise the auto-generated `job_N`
4812
+ positional token assigned by the server during request
4813
+ validation (e.g. `job_0`, `job_1`). Workflow-create rejects
4814
+ fire BEFORE persisted server UUIDs are assigned; `job_ref`
4815
+ is the request-local handle that survives across reject
4816
+ and (later) success paths. Per `JobDefinition.id` pattern
4817
+ + auto-generation rules.
4818
+ example: "stitched"
4819
+ input_index:
4820
+ type: integer
4821
+ minimum: 0
4822
+ description: |
4823
+ 0-based ordinal into `JobDefinition.inputs[]` identifying
4824
+ the specific input that violated the per-input ceiling.
4825
+ Set ONLY on `input_*_exceeds_long_form` reasons for
4826
+ multi-input operations; omitted on single-input
4827
+ operations (no positional ambiguity) and on
4828
+ `combined_*_exceeds_long_form` reasons (whole-job
4829
+ violation across all inputs).
4830
+ operation:
4831
+ $ref: '#/components/schemas/OperationType'
4832
+ description: Operation type that triggered the band-ceiling reject.
4833
+ processing_class:
4834
+ $ref: '#/components/schemas/ProcessingClass'
4835
+ description: |
4836
+ The class whose ceiling was exceeded — typically `long_form`
4837
+ or `long_form_re_encode`.
4838
+ actual:
4839
+ type: integer
4840
+ minimum: 0
4841
+ description: |
4842
+ Observed value. Bytes for `*_size_exceeds_long_form`
4843
+ reasons; whole seconds for `*_duration_exceeds_long_form`
4844
+ reasons.
4845
+ ceiling:
4846
+ type: integer
4847
+ minimum: 0
4848
+ description: |
4849
+ Effective per-tier ceiling for this caller (same units as
4850
+ `actual`). The binding cap after `per_tier_constraints`
4851
+ overlay; lets consumers render "X exceeded by Y" without
4852
+ re-deriving caps from the per-tier overlay.
4853
+ required_tier:
4854
+ description: |
4855
+ Optional. When a HIGHER tier exists whose
4856
+ `per_tier_constraints` would accommodate this request, the
4857
+ server SHOULD set `required_tier` to that tier — consumers
4858
+ can offer an upgrade nudge. `null` (or omitted) means
4859
+ **no tier resolves** the overflow (e.g. enterprise already
4860
+ hits the 120 GB hard ceiling per
4861
+ [ADR-0011](../docs/decisions/0011-per-tier-processing-class-constraints.md)
4862
+ D1–D4).
4863
+
4864
+ Distinct from `TierRestrictionResponse.required_tier`
4865
+ which names a tier whose request-level upload cap
4866
+ satisfies the request — this field names a tier whose
4867
+ long-form processing-class cap satisfies it. Per
4868
+ [ADR-0012](../docs/decisions/0012-processing-class-band-reject-envelope.md)
4869
+ for the band-vs-tier split.
4870
+ oneOf:
4871
+ - $ref: '#/components/schemas/UserTier'
4872
+ - type: 'null'
4873
+ documentation_url:
4874
+ type: string
4875
+ format: uri
4876
+ description: Optional link to processing-class documentation.
4877
+ message_key:
4878
+ type: string
4879
+ description: Per I26. See `ErrorEnvelope.message_key`.
4880
+ message:
4881
+ type: string
4882
+ description: |
4883
+ Per I26. Human-readable, localised per `Accept-Language`.
4884
+ Never parse for control flow.
4885
+ locale:
4886
+ type: string
4887
+ description: BCP 47 locale tag. See `ErrorEnvelope.locale`.
4888
+ message_params:
4889
+ type: object
4890
+ additionalProperties: true
4891
+ description: |
4892
+ Per I26. Optional interpolation values for the localised
4893
+ `message`. Excludes cost numbers.
4894
+
4895
+ ProcessingClassExceedsBandResponse:
4896
+ description: |
4897
+ 422 response body when one or more jobs cannot be classified
4898
+ because input size/duration exceeds the `long_form` (or
4899
+ `long_form_re_encode`) ceiling under the caller's effective
4900
+ per-tier caps (per
4901
+ [ADR-0011](../docs/decisions/0011-per-tier-processing-class-constraints.md)
4902
+ `per_tier_constraints`).
4903
+
4904
+ Distinct from `TierRestrictionResponse` (403, request-level
4905
+ tier-quota — resolvable by upload-size reduction or quota
4906
+ change) and from `FeatureNotAvailableResponse` (422, feature
4907
+ tagged not-yet-shipped — resolvable by waiting for the
4908
+ availability flip). Resolution path is per-violation:
4909
+ `required_tier` on each `ProcessingClassBandViolation` names
4910
+ the tier (if any) whose `per_tier_constraints` would
4911
+ accommodate the request; `null` means terminal (e.g. enterprise
4912
+ already at the 120 GB hard ceiling).
4913
+
4914
+ Per
4915
+ [ADR-0012](../docs/decisions/0012-processing-class-band-reject-envelope.md)
4916
+ for the band-vs-tier rationale and routing rule (why this
4917
+ envelope is 422, not an extension of `TierRestrictionResponse`
4918
+ on 403).
4919
+
4920
+ Delivered on `POST /api/workflows` 422 in a naked `oneOf`
4921
+ alongside `ValidationErrorEnvelope` and
4922
+ `FeatureNotAvailableResponse` — branches distinguished by
4923
+ required-field shape (`details` vs `error_type` value).
4924
+ allOf:
4925
+ - $ref: '#/components/schemas/ErrorEnvelope'
4926
+ - type: object
4927
+ required:
4928
+ - error_type
4929
+ - violations
4930
+ properties:
4931
+ error_type:
4932
+ type: string
4933
+ enum:
4934
+ - processing_class_exceeds_band
4935
+ description: Discriminator for the 422 oneOf. Always `processing_class_exceeds_band` for this envelope.
4936
+ violations:
4937
+ type: array
4938
+ minItems: 1
4939
+ description: |
4940
+ One entry per offending job/input. Per ADR-0001 §F6
4941
+ batched-violations rule, multiple violations in a
4942
+ single request are ALL returned here (fail-all, not
4943
+ fail-fast).
4944
+ items:
4945
+ $ref: '#/components/schemas/ProcessingClassBandViolation'
4946
+
4302
4947
  FeatureTierRestrictedResponse:
4303
4948
  description: |
4304
4949
  403 response body when a workflow references one or more features
@@ -4634,11 +5279,18 @@ components:
4634
5279
  multipart_chunk_size:
4635
5280
  type: integer
4636
5281
  format: int64
4637
- const: 5242880
5282
+ const: 16777216
4638
5283
  description: |
4639
5284
  Recommended chunk size in bytes for multipart upload
4640
- chunks (5 MiB / 5,242,880 bytes — 1024-based). Matches
4641
- the existing TS SDK default. The server's
5285
+ chunks (16 MiB / 16,777,216 bytes — 1024-based). Raised
5286
+ from 5 MiB by CON-1 (ADR-0011): S3 caps a multipart
5287
+ upload at 10,000 parts, and the Enterprise envelope is a
5288
+ 120 GB hard ceiling. At 16 MiB a 120 GiB object needs
5289
+ 7,680 parts (≤ 10,000, inside AWS's 16–64 MB recommended
5290
+ band); 5 MiB would need 24,576 and 10 MiB 12,288 — both
5291
+ exceed the S3 limit. **Wire-incompatible change** — SDKs
5292
+ pin this as a compile-time constant, so CON-1 and SDK-2
5293
+ ship as a non-independently-mergeable pair. The server's
4642
5294
  `MultipartInitiateResponse` returns a
4643
5295
  `recommended_chunk_size` per file based on first-chunk
4644
5296
  throughput; SDKs SHOULD prefer that runtime value when
@@ -4807,27 +5459,43 @@ components:
4807
5459
  total_parts:
4808
5460
  type: integer
4809
5461
  minimum: 2
4810
- maximum: 500
5462
+ maximum: 10000
4811
5463
  description: |
4812
5464
  Total number of parts. The client slices the remaining file into
4813
5465
  exactly (total_parts - 1) chunks using recommended_chunk_size.
4814
- The last chunk may be smaller.
5466
+ The last chunk may be smaller. Maximum raised 500 → 10,000 by
5467
+ CON-1 (ADR-0011) — 10,000 is the S3 multipart hard part limit;
5468
+ 500 contract-capped uploads at ≈ 50 GB, below the 120 GB
5469
+ Enterprise envelope.
4815
5470
  example: 5
4816
5471
  recommended_chunk_size:
4817
5472
  type: integer
4818
- minimum: 5242880
5473
+ minimum: 16777216
4819
5474
  maximum: 104857600
4820
5475
  description: |
4821
5476
  Chunk size in bytes for remaining parts. Calculated from first chunk
4822
- throughput * 5s target, clamped to 5MB-100MB. The last chunk may be
4823
- smaller than 5MB.
4824
- example: 10485760
5477
+ throughput * 5s target, clamped to 16 MiB–100 MiB. The last chunk
5478
+ may be smaller than 16 MiB. Minimum raised 5 MiB → 16 MiB by CON-1
5479
+ (ADR-0011) so the runtime value never falls below the
5480
+ `UploadThresholds.multipart_chunk_size` constant SDKs fall back to
5481
+ (the S3 10,000-part limit at the 120 GB Enterprise ceiling).
5482
+ example: 16777216
4825
5483
  presigned_urls:
4826
5484
  type: array
4827
5485
  description: |
4828
5486
  Pre-signed S3 PUT URLs for parts 2 through total_parts.
4829
5487
  Each URL accepts a PUT request with raw chunk bytes as body.
4830
5488
  Collect the ETag from each S3 response for the complete request.
5489
+
5490
+ NOTE (CON-1/ADR-0011): with `total_parts` now bounded by the
5491
+ S3 hard limit (10,000), a maximal Enterprise upload implies a
5492
+ large URL set. The server is NOT required to return every URL
5493
+ in one synchronous response — bounded-batch / paginated URL
5494
+ delivery and resumable re-fetch are owned by API-2
5495
+ (durable upload session) and SDK-3 (presigned batching +
5496
+ paginated ListParts). Consumers MUST NOT assume a single
5497
+ initiate response carries all `total_parts - 1` URLs at the
5498
+ high end of the range; treat this array as the first batch.
4831
5499
  items:
4832
5500
  $ref: '#/components/schemas/PresignedUrlPart'
4833
5501
  constraints_applied:
@@ -4940,6 +5608,249 @@ components:
4940
5608
  data:
4941
5609
  $ref: '#/components/schemas/MultipartCompleteResponse'
4942
5610
 
5611
+ # ============================================
5612
+ # MULTIPART SESSION RESUME SCHEMAS (HxUmVr3Y)
5613
+ # ============================================
5614
+
5615
+ MultipartPartListing:
5616
+ type: object
5617
+ description: |
5618
+ One uploaded part as reported by the S3 multipart ListParts
5619
+ API. The /status response carries an array of these. Mirrors
5620
+ the S3 wire shape verbatim so the response is a 1:1 passthrough
5621
+ with no translation layer.
5622
+ required:
5623
+ - part_number
5624
+ - etag
5625
+ - size_bytes
5626
+ - last_modified
5627
+ properties:
5628
+ part_number:
5629
+ type: integer
5630
+ minimum: 1
5631
+ maximum: 10000
5632
+ description: |
5633
+ S3 multipart part number. Part 1 is always present in a
5634
+ healthy session (uploaded synchronously at `/initiate`);
5635
+ parts 2–N follow.
5636
+ etag:
5637
+ type: string
5638
+ description: |
5639
+ ETag returned by S3 for the part. Quoted MD5 hex by default;
5640
+ preserve quotes verbatim as S3 emits them.
5641
+ example: '"d8e8fca2dc0f896fd7cb4cb0031ba249"'
5642
+ size_bytes:
5643
+ type: integer
5644
+ format: int64
5645
+ minimum: 0
5646
+ description: Part size in bytes (as reported by S3).
5647
+ last_modified:
5648
+ type: string
5649
+ format: date-time
5650
+ description: ISO-8601 timestamp from S3 ListParts `LastModified`.
5651
+
5652
+ MultipartStatusResponse:
5653
+ type: object
5654
+ description: |
5655
+ Resume-state snapshot for an in-flight multipart session. The
5656
+ `data` payload on `GET /api/uploads/multipart/{uploadId}/status`.
5657
+ required:
5658
+ - upload_id
5659
+ - multipart_upload_id
5660
+ - cloud_key
5661
+ - total_parts
5662
+ - uploaded_parts
5663
+ - next_part_number_marker
5664
+ - is_truncated
5665
+ - manifest_expires_at
5666
+ - recommended_chunk_size
5667
+ properties:
5668
+ upload_id:
5669
+ $ref: '#/components/schemas/UuidV7'
5670
+ description: Session identifier (matches the path `uploadId` and the initiate response `upload_id`).
5671
+ multipart_upload_id:
5672
+ type: string
5673
+ description: |
5674
+ S3 multipart upload identifier returned by `CreateMultipartUpload`.
5675
+ Opaque to API consumers; emitted for diagnostic visibility
5676
+ (SDK logs / dashboards correlating against AWS CloudTrail).
5677
+ cloud_key:
5678
+ type: string
5679
+ description: |
5680
+ S3 object key under which the assembled object will be
5681
+ stored on `multipart/complete`. Opaque to consumers.
5682
+ total_parts:
5683
+ type: integer
5684
+ minimum: 2
5685
+ maximum: 10000
5686
+ description: |
5687
+ Total number of parts the client must upload to complete
5688
+ the session. Same value as `MultipartInitiateResponse.total_parts`
5689
+ and stable for the lifetime of the session.
5690
+ uploaded_parts:
5691
+ type: array
5692
+ description: |
5693
+ Parts already present in S3 for this session, as reported
5694
+ by S3 ListParts at request time. May be empty (no parts
5695
+ uploaded yet) or partial (resume mid-upload). Order is the
5696
+ S3-native part-number ascending.
5697
+ items:
5698
+ $ref: '#/components/schemas/MultipartPartListing'
5699
+ next_part_number_marker:
5700
+ description: |
5701
+ S3 ListParts cursor — pass this as the next request's
5702
+ `cursor` query parameter to fetch the following page.
5703
+ `null` on the final page (or when `is_truncated: false`).
5704
+ Mirrors the S3 `NextPartNumberMarker` field verbatim.
5705
+
5706
+ Upper bound matches the request `cursor` query parameter
5707
+ range (`0..9999`) so SDKs can round-trip the marker
5708
+ verbatim — `total_parts` caps at 10,000 and the cursor
5709
+ semantically means "list after part N", so the highest
5710
+ reachable marker is 9,999 (any cursor of 10,000 would
5711
+ return an empty page).
5712
+ oneOf:
5713
+ - type: integer
5714
+ minimum: 0
5715
+ maximum: 9999
5716
+ - type: 'null'
5717
+ is_truncated:
5718
+ type: boolean
5719
+ description: |
5720
+ `true` when more pages remain; `false` on the final page.
5721
+ Mirrors the S3 ListParts `IsTruncated` field verbatim.
5722
+ manifest_expires_at:
5723
+ description: |
5724
+ ISO-8601 expiry timestamp of the session manifest. `null`
5725
+ when the TTL has lapsed or was not initialised — in that
5726
+ case, callers SHOULD invoke
5727
+ `POST /api/uploads/multipart/{uploadId}/keepalive` to
5728
+ re-establish a 48 h window before re-presigning. The
5729
+ manifest TTL is decoupled from individual presigned-URL
5730
+ TTLs.
5731
+ oneOf:
5732
+ - type: string
5733
+ format: date-time
5734
+ - type: 'null'
5735
+ recommended_chunk_size:
5736
+ type: integer
5737
+ minimum: 16777216
5738
+ maximum: 104857600
5739
+ description: |
5740
+ Chunk size (bytes) the server recommends for any remaining
5741
+ parts in this session — identical to
5742
+ `MultipartInitiateResponse.recommended_chunk_size` (16 MiB
5743
+ floor / 100 MiB ceiling per CON-1 / ADR-0011). Returned on
5744
+ every page so the client doesn't need to retain the
5745
+ initiate response across a resume.
5746
+
5747
+ MultipartStatusSuccessEnvelope:
5748
+ type: object
5749
+ required:
5750
+ - success
5751
+ - data
5752
+ properties:
5753
+ success:
5754
+ type: boolean
5755
+ enum: [true]
5756
+ data:
5757
+ $ref: '#/components/schemas/MultipartStatusResponse'
5758
+
5759
+ MultipartPresignRequest:
5760
+ type: object
5761
+ description: |
5762
+ Caller-supplied subset of part numbers to re-presign. Request
5763
+ body for `POST /api/uploads/multipart/{uploadId}/presign`.
5764
+ required:
5765
+ - part_numbers
5766
+ properties:
5767
+ part_numbers:
5768
+ type: array
5769
+ minItems: 1
5770
+ maxItems: 100
5771
+ uniqueItems: true
5772
+ description: |
5773
+ Part numbers to re-presign. Each entry MUST satisfy
5774
+ `2 ≤ n ≤ total_parts` from the initiate response —
5775
+ **Part 1 is rejected** because the manifest stores its
5776
+ ETag from `/initiate` and re-presigning would break the
5777
+ eventual `multipart/complete` call. Cap of 100 entries
5778
+ per request; SDKs paginate larger resume sets across
5779
+ multiple `/presign` calls.
5780
+ items:
5781
+ type: integer
5782
+ minimum: 2
5783
+ maximum: 10000
5784
+
5785
+ MultipartPresignResponse:
5786
+ type: object
5787
+ description: |
5788
+ Pre-signed URLs for the parts requested via
5789
+ `MultipartPresignRequest.part_numbers`. The `data` payload on
5790
+ `POST /api/uploads/multipart/{uploadId}/presign`.
5791
+ required:
5792
+ - upload_id
5793
+ - presigned_urls
5794
+ properties:
5795
+ upload_id:
5796
+ $ref: '#/components/schemas/UuidV7'
5797
+ description: Session identifier (echoes the path `uploadId`).
5798
+ presigned_urls:
5799
+ type: array
5800
+ minItems: 1
5801
+ maxItems: 100
5802
+ description: |
5803
+ One pre-signed PUT URL per requested part number, in the
5804
+ same order as `MultipartPresignRequest.part_numbers`. Each
5805
+ item carries `part_number` + `url` + `expires_at` —
5806
+ same shape as `MultipartInitiateResponse.presigned_urls[]`.
5807
+ items:
5808
+ $ref: '#/components/schemas/PresignedUrlPart'
5809
+
5810
+ MultipartPresignSuccessEnvelope:
5811
+ type: object
5812
+ required:
5813
+ - success
5814
+ - data
5815
+ properties:
5816
+ success:
5817
+ type: boolean
5818
+ enum: [true]
5819
+ data:
5820
+ $ref: '#/components/schemas/MultipartPresignResponse'
5821
+
5822
+ MultipartKeepaliveResponse:
5823
+ type: object
5824
+ description: |
5825
+ Refreshed manifest TTL for an in-flight multipart session. The
5826
+ `data` payload on `POST /api/uploads/multipart/{uploadId}/keepalive`.
5827
+ required:
5828
+ - upload_id
5829
+ - manifest_expires_at
5830
+ properties:
5831
+ upload_id:
5832
+ $ref: '#/components/schemas/UuidV7'
5833
+ description: Session identifier (echoes the path `uploadId`).
5834
+ manifest_expires_at:
5835
+ type: string
5836
+ format: date-time
5837
+ description: |
5838
+ ISO-8601 expiry timestamp of the refreshed manifest. Always
5839
+ non-null on a successful 200 response — keepalive
5840
+ unconditionally extends the TTL to 48 h ahead of `now`.
5841
+
5842
+ MultipartKeepaliveSuccessEnvelope:
5843
+ type: object
5844
+ required:
5845
+ - success
5846
+ - data
5847
+ properties:
5848
+ success:
5849
+ type: boolean
5850
+ enum: [true]
5851
+ data:
5852
+ $ref: '#/components/schemas/MultipartKeepaliveResponse'
5853
+
4943
5854
  # ============================================
4944
5855
  # METADATA SCHEMAS
4945
5856
  # ============================================
@@ -6293,6 +7204,21 @@ components:
6293
7204
  description: Progress percentage (0-100). Present when in_progress or completed.
6294
7205
  result:
6295
7206
  $ref: '#/components/schemas/OperationResult'
7207
+ error_code:
7208
+ type: string
7209
+ description: |
7210
+ Machine-readable failure code. Present when `status` is `failed`;
7211
+ absent otherwise. Mirrors `SseOperationFailedData.error_code` — the
7212
+ same diagnostic the SSE `operation.failed` event carries, surfaced
7213
+ here for polling consumers. Plain string (consumers duck-type on
7214
+ it), e.g. `output_too_large`.
7215
+ example: "output_too_large"
7216
+ error_message:
7217
+ type: string
7218
+ description: |
7219
+ Human-readable failure detail. Present when `status` is `failed`;
7220
+ absent otherwise. Mirrors `SseOperationFailedData.error_message`.
7221
+ example: "output_too_large: Output (12156489 bytes) is not smaller than input (6187609 bytes)"
6296
7222
 
6297
7223
  OperationResult:
6298
7224
  type: object
@@ -6370,12 +7296,37 @@ components:
6370
7296
 
6371
7297
  OperationDownload:
6372
7298
  type: object
7299
+ description: |
7300
+ A single deliverable output file for an operation. For multi-output
7301
+ fan-out (e.g. convert PDF->image emits one file per page), each entry
7302
+ carries an indexing field. This is the REST projection of the same
7303
+ indexing model the AsyncAPI `OperationResultOutputEntry` defines per
7304
+ ADR-0009 §D2 — `page_index` for PDF-page outputs, `position` for
7305
+ generic ordinals, mutually exclusive within an entry.
6373
7306
  required:
6374
7307
  - operation
6375
7308
  - operation_id
6376
7309
  - filename
6377
7310
  - size_bytes
6378
7311
  - download_url
7312
+ oneOf:
7313
+ - title: PageIndexed
7314
+ description: PDF-page output (convert PDF->image).
7315
+ required: [page_index]
7316
+ not: { required: [position] }
7317
+ - title: PositionIndexed
7318
+ description: Generic ordinal output (frame strip, chapter split).
7319
+ required: [position]
7320
+ not: { required: [page_index] }
7321
+ - title: Unindexed
7322
+ description: |
7323
+ Output without an explicit indexing field — every legacy
7324
+ single-output download. Schema-valid; emitted by all
7325
+ non-fan-out operations.
7326
+ not:
7327
+ anyOf:
7328
+ - required: [page_index]
7329
+ - required: [position]
6379
7330
  properties:
6380
7331
  operation:
6381
7332
  type: string
@@ -6394,6 +7345,26 @@ components:
6394
7345
  type: string
6395
7346
  format: uri
6396
7347
  description: Pre-signed download URL
7348
+ page_index:
7349
+ type: integer
7350
+ minimum: 1
7351
+ description: |
7352
+ 1-based page number for PDF-page fan-out outputs (convert
7353
+ PDF->image). Gapless within an operation (an N-page conversion
7354
+ emits `page_index` 1..N). Mutually exclusive with `position`.
7355
+ Absent on non-indexed (single-output) downloads. Mirrors
7356
+ `OperationResultOutputEntry.page_index`. Per ADR-0009 §D2.
7357
+ example: 1
7358
+ position:
7359
+ type: integer
7360
+ minimum: 0
7361
+ description: |
7362
+ 0-based ordinal for non-PDF multi-output operations (e.g. frame
7363
+ strip, chapter split). Mutually exclusive with `page_index`.
7364
+ Absent on non-indexed downloads. Forward-looking — not emitted by
7365
+ any current operation; declared for parity with
7366
+ `OperationResultOutputEntry.position`. Per ADR-0009 §D2.
7367
+ example: 0
6397
7368
 
6398
7369
  # ============================================
6399
7370
  # SSE EVENT SCHEMAS