@giveitsmaller/contracts 0.72.0 → 0.76.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 (558) hide show
  1. package/README.md +2 -2
  2. package/accepted-options/accepted-options.json +1 -1
  3. package/accepted-options/image-output-routes.json +1 -1
  4. package/asyncapi/events.yaml +209 -67
  5. package/availability/availability.json +93 -73
  6. package/code-builder/code-builder-metadata.json +155 -71
  7. package/dist/asyncapi/ErrorCode.d.ts +1 -0
  8. package/dist/asyncapi/ErrorCode.js +1 -0
  9. package/dist/asyncapi/Failure.d.ts +2 -0
  10. package/dist/asyncapi/LongFormJobMessage.d.ts +1 -0
  11. package/dist/asyncapi/MultiOutputCompletion.d.ts +2 -0
  12. package/dist/asyncapi/OperationMetrics.d.ts +2 -0
  13. package/dist/asyncapi/SingleOutputCompletion.d.ts +2 -0
  14. package/dist/openapi/models/AccountLimitEntry.d.ts +2 -2
  15. package/dist/openapi/models/AccountLimitEntry.js +2 -2
  16. package/dist/openapi/models/AccountLimits.d.ts +2 -2
  17. package/dist/openapi/models/AccountLimits.js +2 -2
  18. package/dist/openapi/models/AccountLimitsLimits.d.ts +14 -2
  19. package/dist/openapi/models/AccountLimitsLimits.js +6 -2
  20. package/dist/openapi/models/AccountLimitsSuccessEnvelope.d.ts +2 -2
  21. package/dist/openapi/models/AccountLimitsSuccessEnvelope.js +2 -2
  22. package/dist/openapi/models/AudioWatermarkDecodeRequest.d.ts +2 -2
  23. package/dist/openapi/models/AudioWatermarkDecodeRequest.js +2 -2
  24. package/dist/openapi/models/AudioWatermarkDecodeResponse.d.ts +2 -2
  25. package/dist/openapi/models/AudioWatermarkDecodeResponse.js +2 -2
  26. package/dist/openapi/models/AuthErrorResponse.d.ts +16 -6
  27. package/dist/openapi/models/AuthErrorResponse.js +2 -2
  28. package/dist/openapi/models/AuthErrorType.d.ts +2 -2
  29. package/dist/openapi/models/AuthErrorType.js +2 -2
  30. package/dist/openapi/models/AuthRejectionEnvelope.d.ts +2 -2
  31. package/dist/openapi/models/AuthRejectionEnvelope.js +2 -2
  32. package/dist/openapi/models/AuthenticatedIdentity.d.ts +2 -2
  33. package/dist/openapi/models/AuthenticatedIdentity.js +2 -2
  34. package/dist/openapi/models/AvailabilityValue.d.ts +2 -2
  35. package/dist/openapi/models/AvailabilityValue.js +2 -2
  36. package/dist/openapi/models/BalanceExhaustedResponse.d.ts +16 -6
  37. package/dist/openapi/models/BalanceExhaustedResponse.js +2 -2
  38. package/dist/openapi/models/BalanceExhaustedResponseAllOfLinks.d.ts +2 -2
  39. package/dist/openapi/models/BalanceExhaustedResponseAllOfLinks.js +2 -2
  40. package/dist/openapi/models/BillingCheckoutRequest.d.ts +2 -2
  41. package/dist/openapi/models/BillingCheckoutRequest.js +2 -2
  42. package/dist/openapi/models/BillingCheckoutSession.d.ts +2 -2
  43. package/dist/openapi/models/BillingCheckoutSession.js +2 -2
  44. package/dist/openapi/models/BillingCheckoutSuccessEnvelope.d.ts +2 -2
  45. package/dist/openapi/models/BillingCheckoutSuccessEnvelope.js +2 -2
  46. package/dist/openapi/models/CallbackEventType.d.ts +2 -2
  47. package/dist/openapi/models/CallbackEventType.js +2 -2
  48. package/dist/openapi/models/CancelAccountDeletion200Response.d.ts +2 -2
  49. package/dist/openapi/models/CancelAccountDeletion200Response.js +2 -2
  50. package/dist/openapi/models/CancelAccountDeletion200ResponseData.d.ts +2 -2
  51. package/dist/openapi/models/CancelAccountDeletion200ResponseData.js +2 -2
  52. package/dist/openapi/models/CapabilityCondition.d.ts +2 -2
  53. package/dist/openapi/models/CapabilityCondition.js +2 -2
  54. package/dist/openapi/models/CapabilityConditionOneOf.d.ts +2 -2
  55. package/dist/openapi/models/CapabilityConditionOneOf.js +2 -2
  56. package/dist/openapi/models/CapabilityConditionOneOf1.d.ts +2 -2
  57. package/dist/openapi/models/CapabilityConditionOneOf1.js +2 -2
  58. package/dist/openapi/models/CapabilityConditionOneOf2.d.ts +2 -2
  59. package/dist/openapi/models/CapabilityConditionOneOf2.js +2 -2
  60. package/dist/openapi/models/CapabilityConditionOneOf3.d.ts +2 -2
  61. package/dist/openapi/models/CapabilityConditionOneOf3.js +2 -2
  62. package/dist/openapi/models/CapabilityConditionOneOf4.d.ts +2 -2
  63. package/dist/openapi/models/CapabilityConditionOneOf4.js +2 -2
  64. package/dist/openapi/models/CapabilityConditionOneOf5.d.ts +2 -2
  65. package/dist/openapi/models/CapabilityConditionOneOf5.js +2 -2
  66. package/dist/openapi/models/CapabilityConditionOneOf6.d.ts +2 -2
  67. package/dist/openapi/models/CapabilityConditionOneOf6.js +2 -2
  68. package/dist/openapi/models/CapabilityConstraint.d.ts +2 -2
  69. package/dist/openapi/models/CapabilityConstraint.js +2 -2
  70. package/dist/openapi/models/CapabilityInputSpec.d.ts +2 -2
  71. package/dist/openapi/models/CapabilityInputSpec.js +2 -2
  72. package/dist/openapi/models/CapabilityProduces.d.ts +2 -2
  73. package/dist/openapi/models/CapabilityProduces.js +2 -2
  74. package/dist/openapi/models/CapabilityProducesOneOf.d.ts +2 -2
  75. package/dist/openapi/models/CapabilityProducesOneOf.js +2 -2
  76. package/dist/openapi/models/CapabilityProducesOneOf1.d.ts +2 -2
  77. package/dist/openapi/models/CapabilityProducesOneOf1.js +2 -2
  78. package/dist/openapi/models/CapabilityProducesOneOf2.d.ts +2 -2
  79. package/dist/openapi/models/CapabilityProducesOneOf2.js +2 -2
  80. package/dist/openapi/models/ChangePasswordRequest.d.ts +2 -2
  81. package/dist/openapi/models/ChangePasswordRequest.js +2 -2
  82. package/dist/openapi/models/CheckoutSessionStatusResponse.d.ts +46 -0
  83. package/dist/openapi/models/CheckoutSessionStatusResponse.js +54 -0
  84. package/dist/openapi/models/CheckoutSessionStatusResponseData.d.ts +50 -0
  85. package/dist/openapi/models/CheckoutSessionStatusResponseData.js +55 -0
  86. package/dist/openapi/models/CodegenSource.d.ts +5 -4
  87. package/dist/openapi/models/CodegenSource.js +2 -2
  88. package/dist/openapi/models/CodegenSourceInput.d.ts +2 -2
  89. package/dist/openapi/models/CodegenSourceInput.js +2 -2
  90. package/dist/openapi/models/CodegenSourceJob.d.ts +2 -2
  91. package/dist/openapi/models/CodegenSourceJob.js +2 -2
  92. package/dist/openapi/models/CodegenSourceJobSource.d.ts +2 -2
  93. package/dist/openapi/models/CodegenSourceJobSource.js +2 -2
  94. package/dist/openapi/models/CodegenSourceOperation.d.ts +2 -2
  95. package/dist/openapi/models/CodegenSourceOperation.js +2 -2
  96. package/dist/openapi/models/CodegenUploadPlaceholder.d.ts +2 -2
  97. package/dist/openapi/models/CodegenUploadPlaceholder.js +2 -2
  98. package/dist/openapi/models/CompositionPlan.d.ts +2 -2
  99. package/dist/openapi/models/CompositionPlan.js +2 -2
  100. package/dist/openapi/models/CompositionPlanJob.d.ts +2 -2
  101. package/dist/openapi/models/CompositionPlanJob.js +2 -2
  102. package/dist/openapi/models/CompositionPlanOperation.d.ts +2 -2
  103. package/dist/openapi/models/CompositionPlanOperation.js +2 -2
  104. package/dist/openapi/models/ConfirmEmailChange200Response.d.ts +2 -2
  105. package/dist/openapi/models/ConfirmEmailChange200Response.js +2 -2
  106. package/dist/openapi/models/ConfirmEmailChange200ResponseData.d.ts +2 -2
  107. package/dist/openapi/models/ConfirmEmailChange200ResponseData.js +2 -2
  108. package/dist/openapi/models/ConfirmEmailChangeRequest.d.ts +2 -2
  109. package/dist/openapi/models/ConfirmEmailChangeRequest.js +2 -2
  110. package/dist/openapi/models/ConnectionSource.d.ts +2 -2
  111. package/dist/openapi/models/ConnectionSource.js +2 -2
  112. package/dist/openapi/models/ContactRequest.d.ts +2 -2
  113. package/dist/openapi/models/ContactRequest.js +2 -2
  114. package/dist/openapi/models/ContactSubject.d.ts +2 -2
  115. package/dist/openapi/models/ContactSubject.js +2 -2
  116. package/dist/openapi/models/ContactValidationErrorResponse.d.ts +2 -2
  117. package/dist/openapi/models/ContactValidationErrorResponse.js +2 -2
  118. package/dist/openapi/models/CreateApiKey201Response.d.ts +2 -2
  119. package/dist/openapi/models/CreateApiKey201Response.js +2 -2
  120. package/dist/openapi/models/CreateApiKey201ResponseData.d.ts +2 -2
  121. package/dist/openapi/models/CreateApiKey201ResponseData.js +2 -2
  122. package/dist/openapi/models/CreateApiKeyRequest.d.ts +2 -2
  123. package/dist/openapi/models/CreateApiKeyRequest.js +2 -2
  124. package/dist/openapi/models/CreateBillingCheckoutSession422Response.d.ts +2 -2
  125. package/dist/openapi/models/CreateBillingCheckoutSession422Response.js +2 -2
  126. package/dist/openapi/models/CreateExternalImport403Response.d.ts +2 -2
  127. package/dist/openapi/models/CreateExternalImport403Response.js +2 -2
  128. package/dist/openapi/models/CreateExternalImport422Response.d.ts +2 -2
  129. package/dist/openapi/models/CreateExternalImport422Response.js +2 -2
  130. package/dist/openapi/models/CreateWorkflow401Response.d.ts +16 -6
  131. package/dist/openapi/models/CreateWorkflow401Response.js +2 -2
  132. package/dist/openapi/models/CreateWorkflow422Response.d.ts +2 -2
  133. package/dist/openapi/models/CreateWorkflow422Response.js +2 -2
  134. package/dist/openapi/models/CreditTransaction.d.ts +22 -12
  135. package/dist/openapi/models/CreditTransaction.js +2 -2
  136. package/dist/openapi/models/CreditTransactionSourceBucket.d.ts +2 -2
  137. package/dist/openapi/models/CreditTransactionSourceBucket.js +2 -2
  138. package/dist/openapi/models/CreditsBalanceResponse.d.ts +2 -2
  139. package/dist/openapi/models/CreditsBalanceResponse.js +2 -2
  140. package/dist/openapi/models/CreditsBalanceSuccessEnvelope.d.ts +2 -2
  141. package/dist/openapi/models/CreditsBalanceSuccessEnvelope.js +2 -2
  142. package/dist/openapi/models/CreditsUsageResponse.d.ts +2 -2
  143. package/dist/openapi/models/CreditsUsageResponse.js +2 -2
  144. package/dist/openapi/models/CreditsUsageSuccessEnvelope.d.ts +2 -2
  145. package/dist/openapi/models/CreditsUsageSuccessEnvelope.js +2 -2
  146. package/dist/openapi/models/Delivery.d.ts +2 -2
  147. package/dist/openapi/models/Delivery.js +2 -2
  148. package/dist/openapi/models/DeliveryOutputRef.d.ts +2 -2
  149. package/dist/openapi/models/DeliveryOutputRef.js +2 -2
  150. package/dist/openapi/models/DeliveryPlan.d.ts +2 -2
  151. package/dist/openapi/models/DeliveryPlan.js +2 -2
  152. package/dist/openapi/models/DeliveryPlanOutput.d.ts +2 -2
  153. package/dist/openapi/models/DeliveryPlanOutput.js +2 -2
  154. package/dist/openapi/models/DeliveryPlanReason.d.ts +2 -2
  155. package/dist/openapi/models/DeliveryPlanReason.js +2 -2
  156. package/dist/openapi/models/DeliverySelection.d.ts +2 -2
  157. package/dist/openapi/models/DeliverySelection.js +2 -2
  158. package/dist/openapi/models/DownloadBundle.d.ts +2 -2
  159. package/dist/openapi/models/DownloadBundle.js +2 -2
  160. package/dist/openapi/models/DroppedOption.d.ts +2 -2
  161. package/dist/openapi/models/DroppedOption.js +2 -2
  162. package/dist/openapi/models/EmailNotify.d.ts +2 -2
  163. package/dist/openapi/models/EmailNotify.js +2 -2
  164. package/dist/openapi/models/EmptySuccessEnvelope.d.ts +2 -2
  165. package/dist/openapi/models/EmptySuccessEnvelope.js +2 -2
  166. package/dist/openapi/models/EndpointProjection.d.ts +2 -2
  167. package/dist/openapi/models/EndpointProjection.js +2 -2
  168. package/dist/openapi/models/EndpointProjectionServersInner.d.ts +2 -2
  169. package/dist/openapi/models/EndpointProjectionServersInner.js +2 -2
  170. package/dist/openapi/models/ErrorEnvelope.d.ts +16 -6
  171. package/dist/openapi/models/ErrorEnvelope.js +2 -2
  172. package/dist/openapi/models/EstimateQuality.d.ts +2 -2
  173. package/dist/openapi/models/EstimateQuality.js +2 -2
  174. package/dist/openapi/models/EstimateRange.d.ts +2 -2
  175. package/dist/openapi/models/EstimateRange.js +2 -2
  176. package/dist/openapi/models/ExportAccountData200Response.d.ts +2 -2
  177. package/dist/openapi/models/ExportAccountData200Response.js +2 -2
  178. package/dist/openapi/models/ExportAccountData200ResponseData.d.ts +2 -2
  179. package/dist/openapi/models/ExportAccountData200ResponseData.js +2 -2
  180. package/dist/openapi/models/ExternalDestination.d.ts +2 -2
  181. package/dist/openapi/models/ExternalDestination.js +2 -2
  182. package/dist/openapi/models/ExternalImportCreatedResponse.d.ts +2 -2
  183. package/dist/openapi/models/ExternalImportCreatedResponse.js +2 -2
  184. package/dist/openapi/models/ExternalImportCreatedSuccessEnvelope.d.ts +2 -2
  185. package/dist/openapi/models/ExternalImportCreatedSuccessEnvelope.js +2 -2
  186. package/dist/openapi/models/ExternalImportRequest.d.ts +2 -2
  187. package/dist/openapi/models/ExternalImportRequest.js +2 -2
  188. package/dist/openapi/models/ExternalImportToken.d.ts +2 -2
  189. package/dist/openapi/models/ExternalImportToken.js +2 -2
  190. package/dist/openapi/models/ExternalSource.d.ts +2 -2
  191. package/dist/openapi/models/ExternalSource.js +2 -2
  192. package/dist/openapi/models/FeatureNotAvailableResponse.d.ts +16 -6
  193. package/dist/openapi/models/FeatureNotAvailableResponse.js +2 -2
  194. package/dist/openapi/models/FeatureTierRestrictedResponse.d.ts +16 -6
  195. package/dist/openapi/models/FeatureTierRestrictedResponse.js +2 -2
  196. package/dist/openapi/models/FeatureViolation.d.ts +2 -2
  197. package/dist/openapi/models/FeatureViolation.js +2 -2
  198. package/dist/openapi/models/GetProfile200Response.d.ts +2 -2
  199. package/dist/openapi/models/GetProfile200Response.js +2 -2
  200. package/dist/openapi/models/GetProfile200ResponseData.d.ts +2 -2
  201. package/dist/openapi/models/GetProfile200ResponseData.js +2 -2
  202. package/dist/openapi/models/ImageEncodeCapabilities.d.ts +2 -2
  203. package/dist/openapi/models/ImageEncodeCapabilities.js +2 -2
  204. package/dist/openapi/models/JobDefinition.d.ts +2 -2
  205. package/dist/openapi/models/JobDefinition.js +2 -2
  206. package/dist/openapi/models/JobDownload.d.ts +2 -2
  207. package/dist/openapi/models/JobDownload.js +2 -2
  208. package/dist/openapi/models/JobInputV2.d.ts +2 -2
  209. package/dist/openapi/models/JobInputV2.js +2 -2
  210. package/dist/openapi/models/JobMediaClass.d.ts +2 -2
  211. package/dist/openapi/models/JobMediaClass.js +2 -2
  212. package/dist/openapi/models/JobOutputSource.d.ts +2 -2
  213. package/dist/openapi/models/JobOutputSource.js +2 -2
  214. package/dist/openapi/models/JobResponse.d.ts +2 -2
  215. package/dist/openapi/models/JobResponse.js +2 -2
  216. package/dist/openapi/models/JobStatus.d.ts +2 -2
  217. package/dist/openapi/models/JobStatus.js +2 -2
  218. package/dist/openapi/models/JobType.d.ts +2 -2
  219. package/dist/openapi/models/JobType.js +2 -2
  220. package/dist/openapi/models/LivenessResponse.d.ts +2 -2
  221. package/dist/openapi/models/LivenessResponse.js +2 -2
  222. package/dist/openapi/models/LoginUser200Response.d.ts +2 -2
  223. package/dist/openapi/models/LoginUser200Response.js +2 -2
  224. package/dist/openapi/models/LoginUser200ResponseData.d.ts +2 -2
  225. package/dist/openapi/models/LoginUser200ResponseData.js +2 -2
  226. package/dist/openapi/models/LoginUser200ResponseDataUser.d.ts +2 -2
  227. package/dist/openapi/models/LoginUser200ResponseDataUser.js +2 -2
  228. package/dist/openapi/models/LoginUser401Response.d.ts +16 -6
  229. package/dist/openapi/models/LoginUser401Response.js +2 -2
  230. package/dist/openapi/models/LoginUserRequest.d.ts +2 -2
  231. package/dist/openapi/models/LoginUserRequest.js +2 -2
  232. package/dist/openapi/models/LongFormConcurrencyLimitResponse.d.ts +21 -8
  233. package/dist/openapi/models/LongFormConcurrencyLimitResponse.js +2 -2
  234. package/dist/openapi/models/LongFormConcurrencyLimitResponseAllOfLinks.d.ts +2 -2
  235. package/dist/openapi/models/LongFormConcurrencyLimitResponseAllOfLinks.js +2 -2
  236. package/dist/openapi/models/MetadataResponse.d.ts +2 -2
  237. package/dist/openapi/models/MetadataResponse.js +2 -2
  238. package/dist/openapi/models/MetadataResponseDimensions.d.ts +2 -2
  239. package/dist/openapi/models/MetadataResponseDimensions.js +2 -2
  240. package/dist/openapi/models/MetadataResponseExif.d.ts +2 -2
  241. package/dist/openapi/models/MetadataResponseExif.js +2 -2
  242. package/dist/openapi/models/MetadataResponseExifGps.d.ts +2 -2
  243. package/dist/openapi/models/MetadataResponseExifGps.js +2 -2
  244. package/dist/openapi/models/MetadataSuccessEnvelope.d.ts +2 -2
  245. package/dist/openapi/models/MetadataSuccessEnvelope.js +2 -2
  246. package/dist/openapi/models/MimeGroupSchema.d.ts +64 -15
  247. package/dist/openapi/models/MimeGroupSchema.js +12 -2
  248. package/dist/openapi/models/MultiInputSource.d.ts +2 -2
  249. package/dist/openapi/models/MultiInputSource.js +2 -2
  250. package/dist/openapi/models/MultipartCompleteRequest.d.ts +2 -2
  251. package/dist/openapi/models/MultipartCompleteRequest.js +2 -2
  252. package/dist/openapi/models/MultipartCompleteRequestPartsInner.d.ts +2 -2
  253. package/dist/openapi/models/MultipartCompleteRequestPartsInner.js +2 -2
  254. package/dist/openapi/models/MultipartCompleteResponse.d.ts +2 -2
  255. package/dist/openapi/models/MultipartCompleteResponse.js +2 -2
  256. package/dist/openapi/models/MultipartCompleteSuccessEnvelope.d.ts +2 -2
  257. package/dist/openapi/models/MultipartCompleteSuccessEnvelope.js +2 -2
  258. package/dist/openapi/models/MultipartInitiateRequestMetadataHint.d.ts +2 -2
  259. package/dist/openapi/models/MultipartInitiateRequestMetadataHint.js +2 -2
  260. package/dist/openapi/models/MultipartInitiateResponse.d.ts +2 -2
  261. package/dist/openapi/models/MultipartInitiateResponse.js +2 -2
  262. package/dist/openapi/models/MultipartInitiateSuccessEnvelope.d.ts +2 -2
  263. package/dist/openapi/models/MultipartInitiateSuccessEnvelope.js +2 -2
  264. package/dist/openapi/models/MultipartKeepaliveResponse.d.ts +2 -2
  265. package/dist/openapi/models/MultipartKeepaliveResponse.js +2 -2
  266. package/dist/openapi/models/MultipartKeepaliveSuccessEnvelope.d.ts +2 -2
  267. package/dist/openapi/models/MultipartKeepaliveSuccessEnvelope.js +2 -2
  268. package/dist/openapi/models/MultipartPartListing.d.ts +2 -2
  269. package/dist/openapi/models/MultipartPartListing.js +2 -2
  270. package/dist/openapi/models/MultipartPresignRequest.d.ts +2 -2
  271. package/dist/openapi/models/MultipartPresignRequest.js +2 -2
  272. package/dist/openapi/models/MultipartPresignResponse.d.ts +2 -2
  273. package/dist/openapi/models/MultipartPresignResponse.js +2 -2
  274. package/dist/openapi/models/MultipartPresignSuccessEnvelope.d.ts +2 -2
  275. package/dist/openapi/models/MultipartPresignSuccessEnvelope.js +2 -2
  276. package/dist/openapi/models/MultipartStatusResponse.d.ts +2 -2
  277. package/dist/openapi/models/MultipartStatusResponse.js +2 -2
  278. package/dist/openapi/models/MultipartStatusSuccessEnvelope.d.ts +2 -2
  279. package/dist/openapi/models/MultipartStatusSuccessEnvelope.js +2 -2
  280. package/dist/openapi/models/NotifyConfig.d.ts +9 -5
  281. package/dist/openapi/models/NotifyConfig.js +2 -2
  282. package/dist/openapi/models/OperationCapability.d.ts +2 -2
  283. package/dist/openapi/models/OperationCapability.js +2 -2
  284. package/dist/openapi/models/OperationDefinition.d.ts +2 -2
  285. package/dist/openapi/models/OperationDefinition.js +2 -2
  286. package/dist/openapi/models/OperationDownload.d.ts +2 -2
  287. package/dist/openapi/models/OperationDownload.js +2 -2
  288. package/dist/openapi/models/OperationInputModel.d.ts +2 -2
  289. package/dist/openapi/models/OperationInputModel.js +2 -2
  290. package/dist/openapi/models/OperationMessageParamsValue.d.ts +25 -0
  291. package/dist/openapi/models/OperationMessageParamsValue.js +31 -0
  292. package/dist/openapi/models/OperationResponse.d.ts +36 -2
  293. package/dist/openapi/models/OperationResponse.js +8 -2
  294. package/dist/openapi/models/OperationResult.d.ts +2 -2
  295. package/dist/openapi/models/OperationResult.js +2 -2
  296. package/dist/openapi/models/OperationResultMetadata.d.ts +29 -3
  297. package/dist/openapi/models/OperationResultMetadata.js +6 -2
  298. package/dist/openapi/models/OperationResultMetrics.d.ts +2 -2
  299. package/dist/openapi/models/OperationResultMetrics.js +2 -2
  300. package/dist/openapi/models/OperationSchemaDefinition.d.ts +8 -8
  301. package/dist/openapi/models/OperationSchemaDefinition.js +2 -2
  302. package/dist/openapi/models/OperationStatus.d.ts +2 -2
  303. package/dist/openapi/models/OperationStatus.js +2 -2
  304. package/dist/openapi/models/OperationType.d.ts +11 -5
  305. package/dist/openapi/models/OperationType.js +11 -5
  306. package/dist/openapi/models/OperationsSchemaResponse.d.ts +2 -2
  307. package/dist/openapi/models/OperationsSchemaResponse.js +2 -2
  308. package/dist/openapi/models/OperationsSchemaResponseWorkflowFeatures.d.ts +2 -2
  309. package/dist/openapi/models/OperationsSchemaResponseWorkflowFeatures.js +2 -2
  310. package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesDelivery.d.ts +2 -2
  311. package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesDelivery.js +2 -2
  312. package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesDeliveryMode.d.ts +2 -2
  313. package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesDeliveryMode.js +2 -2
  314. package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesDeliverySelection.d.ts +2 -2
  315. package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesDeliverySelection.js +2 -2
  316. package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesProcessing.d.ts +2 -2
  317. package/dist/openapi/models/OperationsSchemaResponseWorkflowFeaturesProcessing.js +2 -2
  318. package/dist/openapi/models/OptionSchema.d.ts +36 -2
  319. package/dist/openapi/models/OptionSchema.js +10 -2
  320. package/dist/openapi/models/OutputProperties.d.ts +2 -2
  321. package/dist/openapi/models/OutputProperties.js +2 -2
  322. package/dist/openapi/models/OutputPropertiesIsAnimated.d.ts +2 -2
  323. package/dist/openapi/models/OutputPropertiesIsAnimated.js +2 -2
  324. package/dist/openapi/models/PerClassAvailabilityEntry.d.ts +2 -2
  325. package/dist/openapi/models/PerClassAvailabilityEntry.js +2 -2
  326. package/dist/openapi/models/PerRoleCardinalityEntry.d.ts +2 -2
  327. package/dist/openapi/models/PerRoleCardinalityEntry.js +2 -2
  328. package/dist/openapi/models/PerValueAvailabilityEntry.d.ts +2 -2
  329. package/dist/openapi/models/PerValueAvailabilityEntry.js +2 -2
  330. package/dist/openapi/models/PresignedUrlPart.d.ts +2 -2
  331. package/dist/openapi/models/PresignedUrlPart.js +2 -2
  332. package/dist/openapi/models/ProbePendingResponse.d.ts +16 -6
  333. package/dist/openapi/models/ProbePendingResponse.js +2 -2
  334. package/dist/openapi/models/ProcessingClass.d.ts +2 -2
  335. package/dist/openapi/models/ProcessingClass.js +2 -2
  336. package/dist/openapi/models/ProcessingClassBandViolation.d.ts +2 -2
  337. package/dist/openapi/models/ProcessingClassBandViolation.js +2 -2
  338. package/dist/openapi/models/ProcessingClassConstraints.d.ts +2 -2
  339. package/dist/openapi/models/ProcessingClassConstraints.js +2 -2
  340. package/dist/openapi/models/ProcessingClassEntry.d.ts +2 -2
  341. package/dist/openapi/models/ProcessingClassEntry.js +2 -2
  342. package/dist/openapi/models/ProcessingClassExceedsBandResponse.d.ts +16 -6
  343. package/dist/openapi/models/ProcessingClassExceedsBandResponse.js +2 -2
  344. package/dist/openapi/models/ProcessingClassHint.d.ts +2 -2
  345. package/dist/openapi/models/ProcessingClassHint.js +2 -2
  346. package/dist/openapi/models/ProcessingClassReason.d.ts +2 -2
  347. package/dist/openapi/models/ProcessingClassReason.js +2 -2
  348. package/dist/openapi/models/ProcessingClassRejectReason.d.ts +2 -2
  349. package/dist/openapi/models/ProcessingClassRejectReason.js +2 -2
  350. package/dist/openapi/models/ProcessingPlan.d.ts +2 -2
  351. package/dist/openapi/models/ProcessingPlan.js +2 -2
  352. package/dist/openapi/models/ProcessingPlanJob.d.ts +2 -2
  353. package/dist/openapi/models/ProcessingPlanJob.js +2 -2
  354. package/dist/openapi/models/ReEncodeDecision.d.ts +2 -2
  355. package/dist/openapi/models/ReEncodeDecision.js +2 -2
  356. package/dist/openapi/models/ReadinessResponse.d.ts +2 -2
  357. package/dist/openapi/models/ReadinessResponse.js +2 -2
  358. package/dist/openapi/models/RegisterUser422Response.d.ts +2 -2
  359. package/dist/openapi/models/RegisterUser422Response.js +2 -2
  360. package/dist/openapi/models/RegisterUserRequest.d.ts +2 -2
  361. package/dist/openapi/models/RegisterUserRequest.js +2 -2
  362. package/dist/openapi/models/RequestAccountDeletion200Response.d.ts +2 -2
  363. package/dist/openapi/models/RequestAccountDeletion200Response.js +2 -2
  364. package/dist/openapi/models/RequestAccountDeletion200ResponseData.d.ts +2 -2
  365. package/dist/openapi/models/RequestAccountDeletion200ResponseData.js +2 -2
  366. package/dist/openapi/models/RequestAccountDeletionRequest.d.ts +2 -2
  367. package/dist/openapi/models/RequestAccountDeletionRequest.js +2 -2
  368. package/dist/openapi/models/ResendVerificationEmailRequest.d.ts +2 -2
  369. package/dist/openapi/models/ResendVerificationEmailRequest.js +2 -2
  370. package/dist/openapi/models/ResetPasswordRequest.d.ts +2 -2
  371. package/dist/openapi/models/ResetPasswordRequest.js +2 -2
  372. package/dist/openapi/models/ResponseEnvelope.d.ts +2 -2
  373. package/dist/openapi/models/ResponseEnvelope.js +2 -2
  374. package/dist/openapi/models/RetryResponse.d.ts +2 -2
  375. package/dist/openapi/models/RetryResponse.js +2 -2
  376. package/dist/openapi/models/RetrySuccessEnvelope.d.ts +2 -2
  377. package/dist/openapi/models/RetrySuccessEnvelope.js +2 -2
  378. package/dist/openapi/models/SseCompletionBase.d.ts +2 -2
  379. package/dist/openapi/models/SseCompletionBase.js +2 -2
  380. package/dist/openapi/models/SseConnectionLimitResponse.d.ts +183 -0
  381. package/dist/openapi/models/SseConnectionLimitResponse.js +65 -0
  382. package/dist/openapi/models/SseEventType.d.ts +2 -2
  383. package/dist/openapi/models/SseEventType.js +2 -2
  384. package/dist/openapi/models/SseJobCompletedData.d.ts +2 -2
  385. package/dist/openapi/models/SseJobCompletedData.js +2 -2
  386. package/dist/openapi/models/SseJobFailedData.d.ts +2 -2
  387. package/dist/openapi/models/SseJobFailedData.js +2 -2
  388. package/dist/openapi/models/SseMultiOutputCompletion.d.ts +2 -2
  389. package/dist/openapi/models/SseMultiOutputCompletion.js +2 -2
  390. package/dist/openapi/models/SseMultiOutputCompletionMetrics.d.ts +2 -2
  391. package/dist/openapi/models/SseMultiOutputCompletionMetrics.js +2 -2
  392. package/dist/openapi/models/SseMultiOutputCompletionWithKind.d.ts +2 -2
  393. package/dist/openapi/models/SseMultiOutputCompletionWithKind.js +2 -2
  394. package/dist/openapi/models/SseMultiOutputResultEntry.d.ts +2 -2
  395. package/dist/openapi/models/SseMultiOutputResultEntry.js +2 -2
  396. package/dist/openapi/models/SseOperationCompletedData.d.ts +2 -2
  397. package/dist/openapi/models/SseOperationCompletedData.js +2 -2
  398. package/dist/openapi/models/SseOperationCompletionResult.d.ts +2 -2
  399. package/dist/openapi/models/SseOperationCompletionResult.js +2 -2
  400. package/dist/openapi/models/SseOperationFailedData.d.ts +33 -2
  401. package/dist/openapi/models/SseOperationFailedData.js +8 -2
  402. package/dist/openapi/models/SseOperationProgressData.d.ts +2 -2
  403. package/dist/openapi/models/SseOperationProgressData.js +2 -2
  404. package/dist/openapi/models/SseSingleOutputCompletion.d.ts +2 -2
  405. package/dist/openapi/models/SseSingleOutputCompletion.js +2 -2
  406. package/dist/openapi/models/SseWorkflowTerminalData.d.ts +2 -2
  407. package/dist/openapi/models/SseWorkflowTerminalData.js +2 -2
  408. package/dist/openapi/models/TierRestrictionKind.d.ts +2 -2
  409. package/dist/openapi/models/TierRestrictionKind.js +2 -2
  410. package/dist/openapi/models/TierRestrictionResponse.d.ts +16 -6
  411. package/dist/openapi/models/TierRestrictionResponse.js +2 -2
  412. package/dist/openapi/models/UpdateProfile200Response.d.ts +2 -2
  413. package/dist/openapi/models/UpdateProfile200Response.js +2 -2
  414. package/dist/openapi/models/UpdateProfile200ResponseData.d.ts +2 -2
  415. package/dist/openapi/models/UpdateProfile200ResponseData.js +2 -2
  416. package/dist/openapi/models/UpdateProfile422Response.d.ts +2 -2
  417. package/dist/openapi/models/UpdateProfile422Response.js +2 -2
  418. package/dist/openapi/models/UpdateProfileRequest.d.ts +2 -2
  419. package/dist/openapi/models/UpdateProfileRequest.js +2 -2
  420. package/dist/openapi/models/UploadConstraintsApplied.d.ts +2 -2
  421. package/dist/openapi/models/UploadConstraintsApplied.js +2 -2
  422. package/dist/openapi/models/UploadDurationExceedsTierResponse.d.ts +16 -6
  423. package/dist/openapi/models/UploadDurationExceedsTierResponse.js +2 -2
  424. package/dist/openapi/models/UploadFile403Response.d.ts +2 -2
  425. package/dist/openapi/models/UploadFile403Response.js +2 -2
  426. package/dist/openapi/models/UploadFile422Response.d.ts +2 -2
  427. package/dist/openapi/models/UploadFile422Response.js +2 -2
  428. package/dist/openapi/models/UploadProbeMediaMetadata.d.ts +2 -2
  429. package/dist/openapi/models/UploadProbeMediaMetadata.js +2 -2
  430. package/dist/openapi/models/UploadProbeProcessingClass.d.ts +6 -5
  431. package/dist/openapi/models/UploadProbeProcessingClass.js +6 -5
  432. package/dist/openapi/models/UploadProbeResponse.d.ts +2 -2
  433. package/dist/openapi/models/UploadProbeResponse.js +2 -2
  434. package/dist/openapi/models/UploadProbeStatus.d.ts +2 -2
  435. package/dist/openapi/models/UploadProbeStatus.js +2 -2
  436. package/dist/openapi/models/UploadProbeSuccessEnvelope.d.ts +2 -2
  437. package/dist/openapi/models/UploadProbeSuccessEnvelope.js +2 -2
  438. package/dist/openapi/models/UploadResponse.d.ts +2 -2
  439. package/dist/openapi/models/UploadResponse.js +2 -2
  440. package/dist/openapi/models/UploadSizeExceedsTierResponse.d.ts +16 -6
  441. package/dist/openapi/models/UploadSizeExceedsTierResponse.js +2 -2
  442. package/dist/openapi/models/UploadSource.d.ts +2 -2
  443. package/dist/openapi/models/UploadSource.js +2 -2
  444. package/dist/openapi/models/UploadSuccessEnvelope.d.ts +2 -2
  445. package/dist/openapi/models/UploadSuccessEnvelope.js +2 -2
  446. package/dist/openapi/models/UploadThresholds.d.ts +2 -2
  447. package/dist/openapi/models/UploadThresholds.js +2 -2
  448. package/dist/openapi/models/UserTier.d.ts +2 -2
  449. package/dist/openapi/models/UserTier.js +2 -2
  450. package/dist/openapi/models/ValidationErrorEnvelope.d.ts +19 -8
  451. package/dist/openapi/models/ValidationErrorEnvelope.js +2 -2
  452. package/dist/openapi/models/ValidationErrorEnvelopeDetailsInner.d.ts +2 -2
  453. package/dist/openapi/models/ValidationErrorEnvelopeDetailsInner.js +2 -2
  454. package/dist/openapi/models/VerifyEmailRequest.d.ts +2 -2
  455. package/dist/openapi/models/VerifyEmailRequest.js +2 -2
  456. package/dist/openapi/models/WarningType.d.ts +2 -2
  457. package/dist/openapi/models/WarningType.js +2 -2
  458. package/dist/openapi/models/WebhookOperationContext.d.ts +2 -2
  459. package/dist/openapi/models/WebhookOperationContext.js +2 -2
  460. package/dist/openapi/models/WebhookPayload.d.ts +2 -2
  461. package/dist/openapi/models/WebhookPayload.js +2 -2
  462. package/dist/openapi/models/WorkflowArchiveResponse.d.ts +2 -2
  463. package/dist/openapi/models/WorkflowArchiveResponse.js +2 -2
  464. package/dist/openapi/models/WorkflowArchiveSuccessEnvelope.d.ts +2 -2
  465. package/dist/openapi/models/WorkflowArchiveSuccessEnvelope.js +2 -2
  466. package/dist/openapi/models/WorkflowCancelBillingEffect.d.ts +7 -6
  467. package/dist/openapi/models/WorkflowCancelBillingEffect.js +7 -6
  468. package/dist/openapi/models/WorkflowCancelResponse.d.ts +2 -2
  469. package/dist/openapi/models/WorkflowCancelResponse.js +2 -2
  470. package/dist/openapi/models/WorkflowCancelSuccessEnvelope.d.ts +2 -2
  471. package/dist/openapi/models/WorkflowCancelSuccessEnvelope.js +2 -2
  472. package/dist/openapi/models/WorkflowCreateRequest.d.ts +11 -14
  473. package/dist/openapi/models/WorkflowCreateRequest.js +2 -2
  474. package/dist/openapi/models/WorkflowCreateResponse.d.ts +2 -2
  475. package/dist/openapi/models/WorkflowCreateResponse.js +2 -2
  476. package/dist/openapi/models/WorkflowCreateSuccessEnvelope.d.ts +2 -2
  477. package/dist/openapi/models/WorkflowCreateSuccessEnvelope.js +2 -2
  478. package/dist/openapi/models/WorkflowCreditSummary.d.ts +2 -2
  479. package/dist/openapi/models/WorkflowCreditSummary.js +2 -2
  480. package/dist/openapi/models/WorkflowDownloadResponse.d.ts +2 -2
  481. package/dist/openapi/models/WorkflowDownloadResponse.js +2 -2
  482. package/dist/openapi/models/WorkflowDownloadSuccessEnvelope.d.ts +2 -2
  483. package/dist/openapi/models/WorkflowDownloadSuccessEnvelope.js +2 -2
  484. package/dist/openapi/models/WorkflowEdge.d.ts +2 -2
  485. package/dist/openapi/models/WorkflowEdge.js +2 -2
  486. package/dist/openapi/models/WorkflowExpiredResponse.d.ts +16 -6
  487. package/dist/openapi/models/WorkflowExpiredResponse.js +2 -2
  488. package/dist/openapi/models/WorkflowListResponse.d.ts +2 -2
  489. package/dist/openapi/models/WorkflowListResponse.js +2 -2
  490. package/dist/openapi/models/WorkflowListSuccessEnvelope.d.ts +2 -2
  491. package/dist/openapi/models/WorkflowListSuccessEnvelope.js +2 -2
  492. package/dist/openapi/models/WorkflowPauseRequiredAction.d.ts +2 -2
  493. package/dist/openapi/models/WorkflowPauseRequiredAction.js +2 -2
  494. package/dist/openapi/models/WorkflowPausedDetail.d.ts +2 -2
  495. package/dist/openapi/models/WorkflowPausedDetail.js +2 -2
  496. package/dist/openapi/models/WorkflowPausedDetailLinks.d.ts +2 -2
  497. package/dist/openapi/models/WorkflowPausedDetailLinks.js +2 -2
  498. package/dist/openapi/models/WorkflowProcessing.d.ts +2 -2
  499. package/dist/openapi/models/WorkflowProcessing.js +2 -2
  500. package/dist/openapi/models/WorkflowRestoreResponse.d.ts +2 -2
  501. package/dist/openapi/models/WorkflowRestoreResponse.js +2 -2
  502. package/dist/openapi/models/WorkflowRestoreSuccessEnvelope.d.ts +2 -2
  503. package/dist/openapi/models/WorkflowRestoreSuccessEnvelope.js +2 -2
  504. package/dist/openapi/models/WorkflowResumeResponse.d.ts +2 -2
  505. package/dist/openapi/models/WorkflowResumeResponse.js +2 -2
  506. package/dist/openapi/models/WorkflowResumeSuccessEnvelope.d.ts +2 -2
  507. package/dist/openapi/models/WorkflowResumeSuccessEnvelope.js +2 -2
  508. package/dist/openapi/models/WorkflowSource.d.ts +2 -2
  509. package/dist/openapi/models/WorkflowSource.js +2 -2
  510. package/dist/openapi/models/WorkflowStatus.d.ts +2 -2
  511. package/dist/openapi/models/WorkflowStatus.js +2 -2
  512. package/dist/openapi/models/WorkflowStatusResponse.d.ts +5 -3
  513. package/dist/openapi/models/WorkflowStatusResponse.js +2 -2
  514. package/dist/openapi/models/WorkflowStatusSuccessEnvelope.d.ts +2 -2
  515. package/dist/openapi/models/WorkflowStatusSuccessEnvelope.js +2 -2
  516. package/dist/openapi/models/WorkflowSummary.d.ts +2 -2
  517. package/dist/openapi/models/WorkflowSummary.js +2 -2
  518. package/dist/openapi/models/WorkflowSummaryJob.d.ts +2 -2
  519. package/dist/openapi/models/WorkflowSummaryJob.js +2 -2
  520. package/dist/openapi/models/WorkflowWarning.d.ts +2 -2
  521. package/dist/openapi/models/WorkflowWarning.js +2 -2
  522. package/dist/openapi/models/WorkflowWarningSeverity.d.ts +2 -2
  523. package/dist/openapi/models/WorkflowWarningSeverity.js +2 -2
  524. package/dist/openapi/models/index.d.ts +4 -0
  525. package/dist/openapi/models/index.js +4 -0
  526. package/dist/openapi/runtime.d.ts +2 -2
  527. package/dist/openapi/runtime.js +2 -2
  528. package/dist/operations/archive.metadata.js +1 -0
  529. package/dist/operations/audio_overlay.metadata.js +1 -2
  530. package/dist/operations/audio_to_video.metadata.js +1 -0
  531. package/dist/operations/audio_watermark.metadata.js +4 -9
  532. package/dist/operations/compress.metadata.js +0 -1
  533. package/dist/operations/convert.metadata.js +0 -1
  534. package/dist/operations/custom_luma.metadata.js +1 -3
  535. package/dist/operations/image_watermark.metadata.js +1 -0
  536. package/dist/operations/merge.metadata.js +1 -1
  537. package/dist/operations/metadata-types.d.ts +2 -0
  538. package/dist/operations/split.metadata.js +12 -4
  539. package/dist/operations/text_watermark.metadata.js +1 -0
  540. package/dist/operations/thumbnail.metadata.js +0 -1
  541. package/dist/operations/transform.metadata.js +0 -1
  542. package/dist/operations/video_text_watermark.metadata.js +2 -1
  543. package/dist/operations/video_watermark.metadata.js +1 -1
  544. package/openapi/README.md +1 -1
  545. package/openapi/api.yaml +743 -189
  546. package/operation-capabilities/operation-capabilities.json +1 -1
  547. package/operations/schemas/audio_overlay.yaml +2 -4
  548. package/operations/schemas/audio_watermark.yaml +34 -33
  549. package/operations/schemas/compress.yaml +265 -165
  550. package/operations/schemas/convert.yaml +12 -2
  551. package/operations/schemas/custom_luma.yaml +5 -7
  552. package/operations/schemas/merge.yaml +8 -3
  553. package/operations/schemas/split.yaml +223 -21
  554. package/operations/schemas/thumbnail.yaml +35 -28
  555. package/operations/schemas/transform.yaml +1 -2
  556. package/operations/schemas/video_text_watermark.yaml +75 -18
  557. package/operations/schemas/video_watermark.yaml +50 -15
  558. package/package.json +3 -3
package/openapi/api.yaml CHANGED
@@ -35,6 +35,20 @@ info:
35
35
  (parser obligation: absent = stable; per-enum-value granularity is the
36
36
  `per_value_availability` primitive landed via ticket I17).
37
37
 
38
+ **Free-text string fields: `x-string-vocabulary` (ticket
39
+ [`Q79yjcFF`](https://trello.com/c/Q79yjcFF)).** A `type: string` field
40
+ with no `enum` that names example values says, as data, what a client
41
+ may do with them (the same marker is used in the AsyncAPI document):
42
+ - `open` — a vocabulary that grows. Each published value keeps its
43
+ meaning, the SET is not closed: switch on the values you know and
44
+ handle an unknown one as the generic case (e.g. `ErrorEnvelope.error`).
45
+ - `advisory` — explanatory text. Display or log it; **never switch on
46
+ it** (e.g. `SseWorkflowTerminalData.reason`).
47
+ - `none` — not a vocabulary at all (an expression or an identifier,
48
+ e.g. `OptionSchema.pattern`).
49
+ A field whose description hedges with "common values" or "free-form"
50
+ must carry the marker; a test enforces it.
51
+
38
52
  **Localisation (per ticket [I26](https://trello.com/c/rcnqwgI4)).**
39
53
 
40
54
  Error responses + paused/blocked workflow statuses carry a localised
@@ -89,7 +103,7 @@ info:
89
103
  of truth instead of hardcoding magic numbers. A runtime
90
104
  `GET /api/uploads/limits` endpoint for dynamic discovery
91
105
  (per-tier / per-environment overrides) is a deferred follow-up.
92
- version: 2.203.0
106
+ version: 2.211.0
93
107
  contact:
94
108
  name: API Support
95
109
 
@@ -250,8 +264,16 @@ paths:
250
264
  tier_restriction, restriction_kind: file_size` instead.
251
265
  - **Pixel dimensions** (`error: IMAGE_DIMENSIONS_TOO_LARGE`) — a
252
266
  decodable raster image whose `width × height` exceeds the
253
- configured pixel ceiling (`UPLOAD_MAX_IMAGE_PIXELS`, default
254
- 16 MP). The server reads dimensions from the file **header** (no
267
+ SINGLE-SHOT pixel ceiling (`UPLOAD_MAX_IMAGE_PIXELS`, default
268
+ 16 MP), sized for the API's inline decode on this endpoint.
269
+ Multipart uploads have their own, higher ceiling
270
+ (`limits.max_multipart_upload_image_pixels`). It is an
271
+ environment setting, so an **authenticated**
272
+ client should read the effective value from
273
+ `limits.max_upload_image_pixels` on `GET /api/v2/account/limits`
274
+ (once the API emits it) rather than hard-code a number. ⚠️ That
275
+ endpoint requires authentication, so an **anonymous** uploader has
276
+ no discovery surface for it yet and learns it from this 413. The server reads dimensions from the file **header** (no
255
277
  full-bitmap decode) and rejects **before** decoding, so a
256
278
  within-byte-limit but huge-dimension image (e.g. a few-KB 26 MP
257
279
  PNG that would decode to ~100 MB) is rejected up front rather than
@@ -276,17 +298,21 @@ paths:
276
298
  '415':
277
299
  description: |
278
300
  Unsupported file type at the contract level (no tier permits
279
- this MIME). For tier-specific MIME restrictions where some
280
- tier does permit the MIME, the server returns 403 with
281
- `error_type: tier_restriction, restriction_kind: mime_type`
282
- instead.
301
+ this MIME): `error: UNSUPPORTED_FILE_TYPE`, flat envelope, never
302
+ retryable and never an upgrade prompt. For tier-specific MIME
303
+ restrictions where some tier does permit the MIME, the server
304
+ returns 403 with `error_type: tier_restriction, restriction_kind:
305
+ mime_type` instead. The file-type check runs before the size
306
+ check, so an unsupported file that is also too large gets this
307
+ 415.
283
308
  content:
284
309
  application/json:
285
310
  schema:
286
311
  $ref: '#/components/schemas/ErrorEnvelope'
287
312
  example:
288
313
  success: false
289
- error: "Unsupported MIME type: application/x-msdownload"
314
+ error: "UNSUPPORTED_FILE_TYPE"
315
+ message: "This file type is not supported."
290
316
  '422':
291
317
  description: |
292
318
  Tier-relative cap exceeded for this upload per ticket
@@ -461,11 +487,22 @@ paths:
461
487
  (across all tiers). For tier-specific size caps below this
462
488
  absolute limit, the server returns 403 with
463
489
  `error_type: tier_restriction, restriction_kind: file_size`.
464
- - **Pixel dimensions** (`error: IMAGE_DIMENSIONS_TOO_LARGE`) — as
465
- declared on `POST /api/uploads`: a decodable raster image whose
466
- `width x height` exceeds the configured pixel ceiling
467
- (`UPLOAD_MAX_IMAGE_PIXELS`, default 16 MP), read from the file
468
- **header** and rejected **before** decoding.
490
+ - **Pixel dimensions** (`error: IMAGE_DIMENSIONS_TOO_LARGE`) — a
491
+ decodable raster image whose `width x height` exceeds the
492
+ MULTIPART pixel ceiling, read from the file **header** and
493
+ rejected **before** decoding. It is a SEPARATE, HIGHER ceiling
494
+ than single-shot's 16 MP (owner ruling 2026-09-24, card
495
+ [`ae4Q1yCb`](https://trello.com/c/ae4Q1yCb)): single-shot's is
496
+ sized for the API's inline decode, which multipart never does,
497
+ and multipart carries ordinary camera photos — **a 24 MP photo
498
+ must pass**. API setting `UPLOAD_MAX_MULTIPART_IMAGE_PIXELS`,
499
+ enforced at multipart initiate. Default 50 MP (hub ruling 2026-09-24, on lambdas'
500
+ recommendation: the image workers declare a 100 MP source cap,
501
+ but none has run a job that large, so it stays at half that
502
+ until a staging proof). It is an API setting, so authenticated
503
+ clients read the effective value from
504
+ `limits.max_multipart_upload_image_pixels`
505
+ (`GET /api/v2/account/limits`) once the API emits it.
469
506
 
470
507
  🔴 **THIS CASE WAS UNDECLARED HERE UNTIL 2026-08-28, AND THIS IS
471
508
  THE PATH IT MATTERS MOST ON.** Multipart exists for LARGE uploads,
@@ -480,9 +517,11 @@ paths:
480
517
  $ref: '#/components/schemas/ErrorEnvelope'
481
518
  '415':
482
519
  description: |
483
- Unsupported file type at the contract level. For tier-specific
484
- MIME restrictions, the server returns 403 with
485
- `error_type: tier_restriction, restriction_kind: mime_type`.
520
+ Unsupported file type at the contract level (no tier permits
521
+ this MIME): `error: UNSUPPORTED_FILE_TYPE`, as on
522
+ `POST /api/uploads`. For tier-specific MIME restrictions, the
523
+ server returns 403 with `error_type: tier_restriction,
524
+ restriction_kind: mime_type`.
486
525
  content:
487
526
  application/json:
488
527
  schema:
@@ -1032,9 +1071,13 @@ paths:
1032
1071
  bad ones before submit.
1033
1072
 
1034
1073
  Per ticket [I28 `KbVAnGCm`](https://trello.com/c/KbVAnGCm).
1035
- `availability: planned` until the cross-repo Lambda support
1036
- ships; the runtime returns `feature_not_available` (422)
1037
- until then. Per Tension 1 (ADR-0001 §1.3).
1074
+ `availability: planned`. The upload-probe Lambda exists and runs
1075
+ asynchronously when an upload is finalised; this endpoint returns
1076
+ the cached result when one exists and `feature_not_available`
1077
+ (422) when none does yet. It does not invoke the probe itself.
1078
+ (A `planned` endpoint that answers 200 is inconsistent with the
1079
+ availability taxonomy; the flip decision is tracked separately,
1080
+ card `kAT0i5A6`.) Per Tension 1 (ADR-0001 §1.3).
1038
1081
 
1039
1082
  **SDK helper intent.** SDKs are expected to expose a
1040
1083
  `client.preflight_clips([file_ids])` helper that compiles to N
@@ -1044,10 +1087,11 @@ paths:
1044
1087
 
1045
1088
  **Tier scoping.** The probe respects the caller's tier — the
1046
1089
  `processing_class_pre_assignment` reflects the same logic
1047
- F8.1 upload-side gating uses (per ticket I15-CONS), so a
1048
- free-tier caller probing a 30-minute video sees
1049
- `blocked` rather than the long-form pre-assignment a
1050
- pro-tier caller would see.
1090
+ F8.1 upload-side gating uses (per ticket I15-CONS), which
1091
+ honours a class's `required_tier`. **Since 2026-09-23 no class
1092
+ carries one** (decision 26, `jLuZvlJe`, `UAQJcOi7`), so the
1093
+ pre-assignment depends on the file's duration and size, not on
1094
+ the caller's tier.
1051
1095
 
1052
1096
  **Idempotent.** Probing the same file_id twice returns the
1053
1097
  same `probed_at` timestamp + result (cached server-side per
@@ -1138,22 +1182,6 @@ paths:
1138
1182
  container: "mov"
1139
1183
  probed_at: "2026-04-26T13:50:00Z"
1140
1184
  processing_class_pre_assignment: "blocked"
1141
- blocked_by_tier:
1142
- summary: Free-tier caller probes a long-form clip
1143
- value:
1144
- success: true
1145
- data:
1146
- file_id: "019539ab-1111-7000-8000-000000000005"
1147
- probe_status: "ok"
1148
- media_metadata:
1149
- duration_seconds: 5400
1150
- width: 1920
1151
- height: 1080
1152
- codec: "h264"
1153
- container: "mp4"
1154
- audio_layout: "stereo"
1155
- probed_at: "2026-04-26T13:50:00Z"
1156
- processing_class_pre_assignment: "blocked"
1157
1185
  '401':
1158
1186
  description: Authentication required.
1159
1187
  content:
@@ -1168,8 +1196,8 @@ paths:
1168
1196
  $ref: '#/components/schemas/ErrorEnvelope'
1169
1197
  '422':
1170
1198
  description: |
1171
- The endpoint is `availability: planned` and the runtime
1172
- Lambda has not yet shipped — returned as
1199
+ No probe result is cached for this upload yet (the probe runs
1200
+ asynchronously after the upload is finalised) — returned as
1173
1201
  `FeatureNotAvailableResponse` with `error_type:
1174
1202
  feature_not_available`. Per Tension 1 (ADR-0001 §1.3).
1175
1203
  content:
@@ -1810,8 +1838,8 @@ paths:
1810
1838
  required_action: "add_credits"
1811
1839
  links:
1812
1840
  top_up: "https://giveitsmaller.com/account/billing/top-up"
1813
- upgrade_plan_free_long_form:
1814
- summary: Free tier; long-form requires pro upgrade
1841
+ upgrade_plan_free_tier:
1842
+ summary: Free tier; the API judged the tier allowance too small for this workload (a balance outcome, not a capability gate)
1815
1843
  value:
1816
1844
  success: false
1817
1845
  error: "Workflow requires more credits than the free tier provides."
@@ -1919,7 +1947,9 @@ paths:
1919
1947
  (`propertyName: error_type`):
1920
1948
  - `validation_error` → `ValidationErrorEnvelope` (carries
1921
1949
  `details[]`; the specific failure is in the `error` machine
1922
- code — `INVALID_OPTIONS`, `REQUIRES_REENCODE`,
1950
+ code — `VALIDATION_FAILED` (an option or value failed
1951
+ validation: unknown key, out of range, wrong type, enum),
1952
+ `REQUIRES_REENCODE`,
1923
1953
  `CYCLIC_WORKFLOW_EDGES`, …). The `REQUIRES_REENCODE` flavour
1924
1954
  (per I16-CONS) reuses this same envelope/`error_type` and is
1925
1955
  distinguished only by its `error` code.
@@ -1972,18 +2002,16 @@ paths:
1972
2002
  probe_pending: '#/components/schemas/ProbePendingResponse'
1973
2003
  examples:
1974
2004
  validation_error:
1975
- summary: Generic validation error (legacy shape)
2005
+ summary: An option failed validation (as the API emits it — VALIDATION_FAILED, details[] of {field, message})
1976
2006
  value:
1977
2007
  success: false
1978
2008
  error_type: "validation_error"
1979
- error: "INVALID_OPTIONS"
2009
+ error: "VALIDATION_FAILED"
1980
2010
  details:
1981
- - operation: "compress"
1982
- option: "quality"
1983
- message: "Must be between 1 and 100"
1984
- - operation: "thumbnail"
1985
- option: "width"
1986
- message: "Required field"
2011
+ - field: "quality"
2012
+ message: "Option 'quality' must be at most 100."
2013
+ - field: "width"
2014
+ message: "Option 'width' is required."
1987
2015
  cyclic_workflow_edges:
1988
2016
  summary: Cyclic or self-referential explicit workflow_edges (g8PPkbNu)
1989
2017
  value:
@@ -2080,8 +2108,10 @@ paths:
2080
2108
 
2081
2109
  1. **Long-form concurrency cap** — the caller already holds the
2082
2110
  maximum number of concurrent in-flight long-form (Fargate)
2083
- workflows their tier permits (Pro 2 / Max 5; Enterprise +
2084
- Free uncapped). Body is `LongFormConcurrencyLimitResponse`:
2111
+ workflows their tier permits (per-tier values are the API's
2112
+ `UserTier.maxConcurrentLongFormJobs` and are not restated
2113
+ here — the restated copy said Free was uncapped while the
2114
+ API capped it). Body is `LongFormConcurrencyLimitResponse`:
2085
2115
  `error: LONG_FORM_CONCURRENCY_LIMIT_EXCEEDED`, `message_key:
2086
2116
  job.long_form_concurrency_exceeded`, a `links.upgrade` CTA,
2087
2117
  and **no `Retry-After`** — the limit clears when an in-flight
@@ -2889,19 +2919,105 @@ paths:
2889
2919
  went too fast; a caller who has opened nothing and is refused
2890
2920
  because the pool is full has not, and sending them to a slow-down
2891
2921
  remedy is a lie. That case is `503`.
2922
+
2923
+ 🔴 **THE LIMIT: 5 OPEN STREAMS PER CALLER** (owner ruling
2924
+ 2026-09-23, tickets [`2nZAmfxH`](https://trello.com/c/2nZAmfxH) /
2925
+ [`rLCBjojv`](https://trello.com/c/rLCBjojv)).
2926
+
2927
+ - **Who "the caller" is.** An authenticated user — every stream
2928
+ that user holds counts, across sessions and API keys. An
2929
+ anonymous caller is counted per anonymous session.
2930
+ ⛔ **The anonymous key MUST be server-derived, never from
2931
+ client-supplied state** (a cookie or header the reader can drop
2932
+ or rotate) — otherwise a capability-only reader mints fresh
2933
+ slots per connection and the limit does not exist for anonymous
2934
+ callers.
2935
+ ⚠️ **What that key is TODAY: the verified capability, i.e. per
2936
+ anonymous WORKFLOW.** An anonymous workflow persists only its
2937
+ capability-token hash, not the session that created it, so "per
2938
+ anonymous session" cannot yet be derived server-side. An
2939
+ anonymous caller with several workflows therefore holds up to
2940
+ the limit on EACH; the start-rate limiter and the global `503`
2941
+ still bound the total. The key widens to the anonymous session
2942
+ when the API persists an anonymous principal at create — that is
2943
+ an API change, not a contract one.
2944
+ - **What counts.** A stream occupies a slot from the moment it is
2945
+ accepted (`200`) until it closes, for any reason. Streams are
2946
+ counted, not starts — this is the limit `events_stream`'s start
2947
+ RATE cannot express (see `503`).
2948
+ - **Admission is an ATOMIC check-and-reserve, before the `200`.**
2949
+ Checking the count and incrementing it as separate steps lets a
2950
+ burst of concurrent requests all observe free capacity and open
2951
+ more than the limit. A reservation whose stream then fails to
2952
+ start MUST be released.
2953
+ - **What is refused.** The request that would open the sixth
2954
+ stream. **A held stream is never evicted to make room** — the
2955
+ caller's existing streams are unaffected.
2956
+ - **A crash cannot lock a caller out.** Slots are held in a shared
2957
+ counter whose entries EXPIRE: a slot whose stream died without
2958
+ closing cleanly is released at the latest when its entry
2959
+ expires. The expiry is the server's to choose; it is the
2960
+ longest a caller can be refused for streams that no longer
2961
+ exist.
2962
+ - ⛔ **An entry MUST NOT expire while its stream is still open.**
2963
+ Either the expiry is at least the stream's maximum lifetime (the
2964
+ server's stream deadline), or the holder refreshes the entry
2965
+ while it streams. Otherwise a caller holding streams past the
2966
+ expiry regains slots it is still using, and the limit silently
2967
+ becomes "5 per expiry window" instead of "5 open".
2968
+
2969
+ ⚠️ **Refusal ends the ATTEMPT, never the workflow.** The workflow
2970
+ keeps running and `/status` keeps answering; a caller refused a
2971
+ stream loses only the push channel, not the result.
2972
+
2973
+ 📌 **TWO `429`s SHARE THIS STATUS, discriminated by `error`:**
2974
+ `SSE_CONNECTION_LIMIT_EXCEEDED` (the open-stream limit above,
2975
+ carrying `open_streams` / `max_streams`) and the generic
2976
+ `TOO_MANY_REQUESTS` from the `events_stream` start-RATE limiter — a
2977
+ plain `ErrorEnvelope`, which validates against the same schema
2978
+ because the two count fields are required only on the first. Both
2979
+ carry `Retry-After` and the same obligation below.
2980
+
2981
+ 🔴 **A BROWSER CANNOT READ `Retry-After` UNLESS IT IS EXPOSED.**
2982
+ It is not a CORS-safelisted response header (Fetch Standard,
2983
+ §CORS-safelisted response-header name), and the stream hosts are
2984
+ cross-origin to the frontend. ⇒ **Every refusal on this endpoint
2985
+ (`429` and `503`), as delivered to a browser, MUST carry the same
2986
+ CORS headers as a `200` from that host AND
2987
+ `Access-Control-Expose-Headers: Retry-After`.** Without the first
2988
+ the browser cannot read the status; without the second it reads
2989
+ the status and not the delay — and the consumer obligation below
2990
+ becomes impossible to meet. The obligation is on whatever layer
2991
+ sets CORS for the stream host, not only on the application.
2892
2992
  headers:
2893
2993
  Retry-After:
2894
- description: Seconds to wait. Delta-seconds, not an HTTP-date.
2994
+ required: true
2995
+ description: |
2996
+ Seconds to wait. Delta-seconds, not an HTTP-date. **Always
2997
+ sent on this status**, and exposed to browsers (see
2998
+ `Access-Control-Expose-Headers` above).
2999
+
3000
+ **CONSUMER OBLIGATION** ([`rLCBjojv`](https://trello.com/c/rLCBjojv)):
3001
+ a client receiving this status **MUST NOT** request another
3002
+ stream for this caller before `Retry-After` has elapsed, and
3003
+ **MUST NOT** treat it as a transport error to be retried on
3004
+ its own schedule — it is a deliberate refusal. The client
3005
+ **MAY** follow the workflow over `/status` meanwhile; that
3006
+ endpoint's own rate limits govern it, and `Retry-After` here
3007
+ governs only the next stream request.
2895
3008
  schema:
2896
3009
  type: integer
3010
+ minimum: 0
2897
3011
  content:
2898
3012
  application/json:
2899
3013
  schema:
2900
- $ref: '#/components/schemas/ErrorEnvelope'
3014
+ $ref: '#/components/schemas/SseConnectionLimitResponse'
2901
3015
  example:
2902
3016
  success: false
2903
3017
  error: SSE_CONNECTION_LIMIT_EXCEEDED
2904
3018
  message: Too many open event streams for this caller.
3019
+ open_streams: 5
3020
+ max_streams: 5
2905
3021
  '503':
2906
3022
  description: |
2907
3023
  **Global stream capacity is exhausted — nothing about this caller.**
@@ -2959,10 +3075,34 @@ paths:
2959
3075
  Its refusal behaviour, **as a SHAPE — the counts and intervals are
2960
3076
  configurable defaults in that repo and are deliberately not
2961
3077
  restated here, because a number copied across a repo boundary rots
2962
- silently**: a non-200 is raised as a *transport error*, retried a
2963
- bounded number of times on a delay, and then falls through to
2964
- `/status` polling with **adaptive backoff** — the interval GROWS
2965
- while the server reports no movement.
3078
+ silently.**
3079
+
3080
+ - **Since 2026-09-23 (`compression_frontend` #485, `17bd8b6`,
3081
+ ticket `nuipMybn` — built against this section's obligation):**
3082
+ a `429` / `503` **carrying `Retry-After` or the API's error
3083
+ envelope** is a deliberate refusal, not a transport error (`SseRefusedError`,
3084
+ carrying the status, the `Retry-After` delay and the `error`
3085
+ code). The reader keeps `/status` polling, reopens the stream
3086
+ only after `Retry-After` has elapsed — a wait that applies to
3087
+ **every** stream that browser tab opens, not only the refused
3088
+ one (it is held in the page, so another tab of the same caller
3089
+ does not share it) —
3090
+ and **never reopens** a refusal that carried no `Retry-After`.
3091
+ ⚠️ **Two edges it does not cover, stated so this is not read as
3092
+ blanket compliance:** an UNSTRUCTURED `503` (a load balancer's,
3093
+ with neither) still takes the transport path below; and a
3094
+ `Retry-After` too large for the browser's timer keeps THAT run on
3095
+ polling but does not set the caller-wide wait, so another stream
3096
+ in the same tab may open before it elapses. This contract sets
3097
+ no upper bound on `Retry-After`.
3098
+ - **Before that (measured 2026-08-25):** a non-200 was raised as a
3099
+ *transport error* and retried a bounded number of times on a
3100
+ fixed delay. Any other non-200 status, and the unstructured `503`
3101
+ above, still takes that transport path.
3102
+
3103
+ Either way the fallback is `/status` polling with **adaptive
3104
+ backoff** — the interval GROWS while the server reports no
3105
+ movement.
2966
3106
 
2967
3107
  ⚠️ **And the `/status` poll is NOT started by the fallback.** It
2968
3108
  runs **in parallel from the outset**, as resilience against a
@@ -2974,8 +3114,9 @@ paths:
2974
3114
  🔴 **SO REFUSAL TRADES CONTINUOUS WORKER OCCUPANCY FOR A HIGHER
2975
3115
  REQUEST RATE.** Both halves matter: a held stream pins one PHP-FPM
2976
3116
  worker for its whole life and refusal genuinely sheds that — a
2977
- short poll is not a held connection — while that client's
2978
- connection attempts and polls go **up**.
3117
+ short poll is not a held connection — while that client's polls go
3118
+ **up**. (Its stream re-attempts no longer do: since #485 they wait
3119
+ out `Retry-After`.)
2979
3120
  ⚠️ **Do not read either half alone.** "Refusal sheds load" invites
2980
3121
  a cap whose success metric moves the wrong way; "refusal increases
2981
3122
  load" argues against having a cap at all, and the occupancy it
@@ -2983,19 +3124,25 @@ paths:
2983
3124
 
2984
3125
  ⚠️ **THAT IS PER-CLIENT AND MEASURED. THE AGGREGATE IS NEITHER.**
2985
3126
  Whether refusing many clients at once produces a synchronised burst
2986
- is **UNMEASURED** — the retry delay is a fixed configured interval
2987
- with no jitter, so refusals issued together are retried together,
2988
- and nothing here has observed what that does in aggregate. **Do not
3127
+ is **UNMEASURED** — refusals issued together with the same
3128
+ `Retry-After` reopen together (the delay is the server's, with no
3129
+ client jitter), and nothing here has observed what that does in
3130
+ aggregate. **Do not
2989
3131
  read "not a storm" out of this section; it says the per-client cost
2990
3132
  is bounded and says nothing about the fleet.**
2991
3133
 
2992
- 📌 **WHAT A REFUSED `fetch` CLIENT SHOULD DO INSTEAD IS NOT YET
2993
- SPECIFIED** — including whether `Retry-After` governs a fallback
2994
- poll interval and not only a reconnect. Falling back to polling
2995
- is also load, merely cheaper. Open on
2996
- [`rLCBjojv`](https://trello.com/c/rLCBjojv); **this block states the
2997
- measured behaviour and deliberately does not invent the
2998
- obligation.**
3134
+ 📌 **WHAT A REFUSED CLIENT MUST DO IS NOW SPECIFIED** — on the
3135
+ `Retry-After` header of this status and of `429`
3136
+ ([`rLCBjojv`](https://trello.com/c/rLCBjojv), decided with the
3137
+ owner's stream-cap ruling of 2026-09-23): no further stream request
3138
+ before `Retry-After` elapses, never retried as a transport error,
3139
+ and `/status` polling permitted under that endpoint's own limits.
3140
+ ⚠️ **`Retry-After` governs the next STREAM request, not a poll
3141
+ interval.** Falling back to polling is still load, merely cheaper.
3142
+ Our frontend meets the obligation since #485 for structured
3143
+ refusals with a timer-sized `Retry-After` (the two edges above are
3144
+ the exceptions); any reader that treats refusal as a transport
3145
+ error does not.
2999
3146
 
3000
3147
  📌 **THE POPULATIONS SPLIT BY READER KIND, NOT BY
3001
3148
  BROWSER-VERSUS-NOT.** The WHATWG rule covers **native
@@ -3003,7 +3150,9 @@ paths:
3003
3150
  safe only by its own code, inside a browser or outside one** — and
3004
3151
  a retry loop treating `429`/`503` as retryable on a fixed interval
3005
3152
  is where a storm is reachable. ⚠️ **Our own frontend is in that
3006
- population, not exempt from it.**
3153
+ population, not exempt from it** — it is safe today because #485
3154
+ made it so, and a regression in its code would not be visible
3155
+ here.
3007
3156
 
3008
3157
  ✅ **For OUR SDKs that is measured, not assumed** (sdks,
3009
3158
  2026-08-22, driven through the BUILT client with a stubbed
@@ -3018,11 +3167,19 @@ paths:
3018
3167
  endpoint would not notice.
3019
3168
  headers:
3020
3169
  Retry-After:
3170
+ required: true
3021
3171
  description: |
3022
3172
  Seconds to wait before retrying. Delta-seconds, not an
3023
- HTTP-date. **Also unreadable by `EventSource`** — see above.
3173
+ HTTP-date. **Always sent on this status. Also unreadable by a native `EventSource`** — see
3174
+ above; a `fetch`-based reader can read it.
3175
+
3176
+ **CONSUMER OBLIGATION** — the same as on `429`: no further
3177
+ stream request before `Retry-After` has elapsed, never retried
3178
+ as a transport error; `/status` polling permitted under that
3179
+ endpoint's own limits.
3024
3180
  schema:
3025
3181
  type: integer
3182
+ minimum: 0
3026
3183
  content:
3027
3184
  application/json:
3028
3185
  schema:
@@ -3062,8 +3219,11 @@ paths:
3062
3219
  - `unspent_reservation_released`: the workflow was in
3063
3220
  `pending` / `in_progress` / `paused_insufficient_credits`,
3064
3221
  and the unspent portion of the original reservation has
3065
- been refunded to the caller's balance. The refund appears
3066
- as a separate `CreditTransaction` with `type: refund`.
3222
+ been refunded to the caller's balance. The return appears
3223
+ as a separate `CreditTransaction` with `type:
3224
+ reservation_release` and `reference_type:
3225
+ workflow_reservation_release` — there is no `type: refund`
3226
+ (the API's ledger type is a closed set that has none).
3067
3227
  - `none`: no refund was issued (e.g. all reserved credits
3068
3228
  were already consumed by completed jobs at cancel time;
3069
3229
  or the workflow was already terminal in a previous cancel
@@ -5738,9 +5898,12 @@ paths:
5738
5898
  `schemas/operations/audio_watermark.yaml` — the operation
5739
5899
  embeds; this endpoint decodes.
5740
5900
 
5741
- **Tier-restricted.** This endpoint is `enterprise`-only. Free
5742
- and `pro` callers receive a 403 `feature_tier_restricted`.
5743
- Anonymous callers receive a 401.
5901
+ **No tier gate** (since 2026-09-23, decision 26 — the paired
5902
+ `audio_watermark` operation lost its `enterprise` gate the same
5903
+ day; `X8m2vbvS`), and no 403 is declared: decode reads an
5904
+ already-uploaded file, so no upload quota applies here. Any
5905
+ authenticated caller may call it once it ships. Anonymous
5906
+ callers receive a 401.
5744
5907
 
5745
5908
  **Scope: own watermarks only.** The decoder will refuse to
5746
5909
  extract from media the caller did not mark themselves
@@ -5761,7 +5924,7 @@ paths:
5761
5924
  `feature_not_available` (422) until the Lambda lands. Per
5762
5925
  Tension 1 (ADR-0001 §1.3).
5763
5926
  operationId: decodeAudioWatermark
5764
- security: [{bearerAuth: []}, {sessionAuth: []}] # required (explicit 401 in response set; tier-gated runtime call)
5927
+ security: [{bearerAuth: []}, {sessionAuth: []}] # required (explicit 401 in response set; authenticated runtime call, no tier gate)
5765
5928
  tags:
5766
5929
  - AudioWatermark
5767
5930
  x-availability: planned
@@ -5784,22 +5947,6 @@ paths:
5784
5947
  application/json:
5785
5948
  schema:
5786
5949
  $ref: '#/components/schemas/ErrorEnvelope'
5787
- '403':
5788
- description: |
5789
- Tier insufficient (free / pro caller) — returned as
5790
- `FeatureTierRestrictedResponse` with
5791
- `error_type: feature_tier_restricted`. Per ADR-0001 §1.3.
5792
- content:
5793
- application/json:
5794
- schema:
5795
- oneOf:
5796
- - $ref: '#/components/schemas/TierRestrictionResponse'
5797
- - $ref: '#/components/schemas/FeatureTierRestrictedResponse'
5798
- discriminator:
5799
- propertyName: error_type
5800
- mapping:
5801
- tier_restriction: '#/components/schemas/TierRestrictionResponse'
5802
- feature_tier_restricted: '#/components/schemas/FeatureTierRestrictedResponse'
5803
5950
  '404':
5804
5951
  description: |
5805
5952
  No watermark detected in the supplied asset, OR the
@@ -5961,9 +6108,11 @@ paths:
5961
6108
  Per ticket [I23 `DffjC3zm`](https://trello.com/c/DffjC3zm).
5962
6109
 
5963
6110
  Each transaction is immutable once written. Workflow-create
5964
- reservations appear here as a single row; refunds appear as
5965
- separate rows referencing the original via `reference_id`
5966
- (and `reference_type: workflow`).
6111
+ reservations appear here as a single row (`reference_type:
6112
+ workflow_reservation`); credits returned appear as separate
6113
+ rows carrying the workflow in `reference_id` and a
6114
+ `reference_type` naming how they came back (see
6115
+ `CreditTransaction.reference_type`).
5967
6116
 
5968
6117
  Default page is 20 transactions, ordered most-recent-first.
5969
6118
  operationId: getCreditsUsage
@@ -6033,7 +6182,7 @@ paths:
6033
6182
  purchased_amount: null
6034
6183
  pricing_version: "v3.2.0"
6035
6184
  description: "Workflow reservation: compress.video short_form"
6036
- reference_type: "workflow"
6185
+ reference_type: "workflow_reservation"
6037
6186
  reference_id: "019539ac-2222-7000-8000-000000000001"
6038
6187
  created_at: "2026-04-26T13:55:00Z"
6039
6188
  - id: "019539ad-3333-7000-8000-aaaaaaaaaa02"
@@ -6048,14 +6197,14 @@ paths:
6048
6197
  purchased_amount: -25
6049
6198
  pricing_version: "v3.2.0"
6050
6199
  description: "Workflow reservation: merge.video long_form_re_encode"
6051
- reference_type: "workflow"
6200
+ reference_type: "workflow_reservation"
6052
6201
  reference_id: "019539ac-2222-7000-8000-000000000002"
6053
6202
  created_at: "2026-04-26T13:54:00Z"
6054
6203
  total: 47
6055
6204
  limit: 20
6056
6205
  offset: 0
6057
- refund_followup:
6058
- summary: Refund row referencing the prior workflow_001 reservation
6206
+ reservation_release_followup:
6207
+ summary: Release row returning the prior workflow_001 reservation
6059
6208
  value:
6060
6209
  success: true
6061
6210
  data:
@@ -6065,7 +6214,7 @@ paths:
6065
6214
  # workflow_001.monthly_balance_after (955); after
6066
6215
  # adds back 45 → 1000.
6067
6216
  - id: "019539ad-3333-7000-8000-aaaaaaaaaa03"
6068
- type: "refund"
6217
+ type: "reservation_release"
6069
6218
  amount: 45
6070
6219
  monthly_balance_before: 955
6071
6220
  monthly_balance_after: 1000
@@ -6075,8 +6224,8 @@ paths:
6075
6224
  monthly_amount: 45
6076
6225
  purchased_amount: null
6077
6226
  pricing_version: "v3.2.0"
6078
- description: "Refund: terminal failure on operation-compression-video"
6079
- reference_type: "workflow"
6227
+ description: "Reservation released: terminal failure on operation-compression-video"
6228
+ reference_type: "workflow_reservation_release"
6080
6229
  reference_id: "019539ac-2222-7000-8000-000000000001"
6081
6230
  created_at: "2026-04-26T13:56:00Z"
6082
6231
  total: 47
@@ -6216,8 +6365,8 @@ paths:
6216
6365
  tier_default: 10485760
6217
6366
  overridden: false
6218
6367
  max_total_input_size_bytes:
6219
- effective: 1073741824
6220
- tier_default: 1073741824
6368
+ effective: 5000000000
6369
+ tier_default: 5000000000
6221
6370
  overridden: false
6222
6371
  enterprise_with_upload_override:
6223
6372
  summary: >-
@@ -6290,8 +6439,11 @@ paths:
6290
6439
  **How to observe the grant:** poll `GET /api/v2/credits/usage`
6291
6440
  for a transaction whose `reference_id` equals the `session_id`
6292
6441
  returned here, and whose `reference_type` is
6293
- `stripe_checkout_session`. That is the only client-observable
6294
- correlation between a checkout and its credits.
6442
+ `stripe_checkout_session`. **Today that is the only
6443
+ client-observable correlation** between a checkout and its credits.
6444
+ `GET /api/billing/checkout/{sessionId}/status` is declared as the
6445
+ second one, but it is `planned` (a `422 feature_not_available`)
6446
+ until the API implements it.
6295
6447
 
6296
6448
  🔴 **MATCH ON `reference_type` + `reference_id`, AND DO NOT
6297
6449
  FILTER ON `type`.** The pack grant is written as an
@@ -6449,7 +6601,7 @@ paths:
6449
6601
  value:
6450
6602
  success: false
6451
6603
  error_type: feature_not_available
6452
- error: FEATURE_NOT_AVAILABLE
6604
+ error: UNPROCESSABLE_ENTITY
6453
6605
  message: "Checkout is not yet available."
6454
6606
  violations:
6455
6607
  - feature: endpoint.billing.checkout
@@ -6515,6 +6667,105 @@ paths:
6515
6667
  schema:
6516
6668
  $ref: '#/components/schemas/ErrorEnvelope'
6517
6669
 
6670
+ /api/billing/checkout/{sessionId}/status:
6671
+ get:
6672
+ summary: Status of a checkout session the caller created
6673
+ description: |
6674
+ Whether the credits for a checkout the caller started have been
6675
+ granted. Ticket [`7cSI8eIa`](https://trello.com/c/7cSI8eIa) — declared
6676
+ BEFORE the API builds it (hub ruling, Option A, 2026-08-29); the API
6677
+ half is [`JHrV4MUg`](https://trello.com/c/JHrV4MUg).
6678
+
6679
+ **Why it exists:** between "checkout created" and "the provider's
6680
+ callback lands" nothing used to record that the session existed or
6681
+ whose it was — so a post-checkout page, asked about the NORMAL
6682
+ page-load state, had nothing to ask. The fix records the session at
6683
+ creation; this endpoint reads that record and the credit ledger.
6684
+
6685
+ | `status` | meaning |
6686
+ |---|---|
6687
+ | `paid` | the purchase this session was for has been applied to the caller's account — for a credit **pack**, a credit transaction referencing this session exists; for a **subscription**, the subscription it started is active on the caller's account |
6688
+ | `pending` | the session is recorded as created BY THE CALLER and its purchase has not been applied yet — **not a failure** |
6689
+ | `unknown` | anything else |
6690
+
6691
+ 🔴 **`unknown` DELIBERATELY COLLAPSES "not yours" WITH "never
6692
+ existed". This is a decision, not missing detail.** Telling them
6693
+ apart would make this endpoint an oracle for whether an arbitrary
6694
+ session id is real — a probe confirming a stranger's purchase exists.
6695
+ The requirement is *paid AND yours*; the honest refusal admits
6696
+ neither. ⛔ **Do not "improve" the answer by distinguishing the two**
6697
+ (a 403 or 404 for someone else's session is the same oracle).
6698
+
6699
+ ⛔ **No provider call on this read path.** It will be polled; a
6700
+ third-party call would turn provider latency and outages into page
6701
+ states and put the secret key on a read path.
6702
+
6703
+ ⛔ **No timing is stated here either** — the reason is the one given
6704
+ on `POST /api/billing/checkout` (the delay is the provider's callback
6705
+ latency, which this system does not measure). `pending` is a normal
6706
+ state to keep polling on, not an error.
6707
+ operationId: getCheckoutSessionStatus
6708
+ security: [{bearerAuth: []}, {sessionAuth: []}] # required; answers only about the caller's own sessions
6709
+ x-identity-scoped: true # a session belongs to the caller who created it
6710
+ x-availability: planned
6711
+ tags:
6712
+ - Billing
6713
+ parameters:
6714
+ - name: sessionId
6715
+ in: path
6716
+ required: true
6717
+ description: The `session_id` returned by `POST /api/billing/checkout`.
6718
+ schema:
6719
+ type: string
6720
+ minLength: 1
6721
+ responses:
6722
+ '200':
6723
+ description: |
6724
+ The session's status for this caller. **Once implemented, always
6725
+ 200 for an authenticated caller**, whatever the session id —
6726
+ `unknown` is the answer for anything not provably the caller's (see
6727
+ the collapse rationale above). While the endpoint is `planned` it
6728
+ answers `422 feature_not_available` instead.
6729
+ content:
6730
+ application/json:
6731
+ schema:
6732
+ $ref: '#/components/schemas/CheckoutSessionStatusResponse'
6733
+ examples:
6734
+ paid:
6735
+ summary: Credits granted
6736
+ value:
6737
+ success: true
6738
+ data:
6739
+ session_id: cs_test_a1b2c3
6740
+ status: paid
6741
+ pending:
6742
+ summary: Recorded for this caller, grant not landed yet
6743
+ value:
6744
+ success: true
6745
+ data:
6746
+ session_id: cs_test_a1b2c3
6747
+ status: pending
6748
+ unknown:
6749
+ summary: Not provably this caller's — or never existed
6750
+ value:
6751
+ success: true
6752
+ data:
6753
+ session_id: cs_test_zzz
6754
+ status: unknown
6755
+ '401':
6756
+ description: Authentication required.
6757
+ content:
6758
+ application/json:
6759
+ schema:
6760
+ $ref: '#/components/schemas/ErrorEnvelope'
6761
+ '422':
6762
+ description: |
6763
+ `feature_not_available` while this endpoint is `planned`.
6764
+ content:
6765
+ application/json:
6766
+ schema:
6767
+ $ref: '#/components/schemas/FeatureNotAvailableResponse'
6768
+
6518
6769
  # ============================================
6519
6770
  # CONTACT ENDPOINT
6520
6771
  # ============================================
@@ -6742,12 +6993,22 @@ components:
6742
6993
  enum: [false]
6743
6994
  error:
6744
6995
  type: string
6996
+ x-string-vocabulary: open
6745
6997
  description: |
6746
- Stable, machine-readable error code (e.g.
6747
- `INVALID_OPTIONS`, `BALANCE_EXHAUSTED`,
6998
+ Machine-readable error code. **Each published code is stable; the
6999
+ SET is open** (`x-string-vocabulary: open`): handle an unknown code
7000
+ as a generic error. E.g.
7001
+ `VALIDATION_FAILED`, `BALANCE_EXHAUSTED`,
6748
7002
  `REQUIRES_REENCODE`). Canonical English; never localised.
6749
7003
  SDKs duck-type on this field for typed error-branch
6750
- helpers.
7004
+ helpers — **except where an HTTP-status-shaped code
7005
+ (`UNPROCESSABLE_ENTITY`, `BAD_REQUEST`, …) covers several
7006
+ branches: there `error_type` is the discriminator.**
7007
+ Example: `POST /api/billing/checkout` answers
7008
+ `UNPROCESSABLE_ENTITY` both when checkout is switched off
7009
+ (`error_type: feature_not_available`) and when a pack or
7010
+ plan is not provisioned (no `error_type`); only
7011
+ `error_type` tells them apart.
6751
7012
 
6752
7013
  Multipart-session resume codes (per ticket
6753
7014
  [`HxUmVr3Y`](https://trello.com/c/HxUmVr3Y), V2.10.0):
@@ -6780,7 +7041,8 @@ components:
6780
7041
  404 response + ADR-0016 Amendment.
6781
7042
  - `LONG_FORM_CONCURRENCY_LIMIT_EXCEEDED` (429) — caller already
6782
7043
  holds the maximum concurrent in-flight long-form workflows
6783
- their tier permits (Pro 2 / Max 5; Enterprise uncapped).
7044
+ their tier permits (values: the API's
7045
+ `UserTier.maxConcurrentLongFormJobs`, not restated here).
6784
7046
  DISTINCT from an infra rate-limit 429: carries no
6785
7047
  `Retry-After` (it clears on workflow completion) and adds a
6786
7048
  `links.upgrade` CTA. `message_key:
@@ -6867,21 +7129,33 @@ components:
6867
7129
  dispatch on `error_type` instead of structural `instanceOf`
6868
7130
  guards (which mis-fire on camelCase-vs-snake_case property
6869
7131
  names). Distinct from the `error` machine code below: `error`
6870
- carries the specific failure code (`INVALID_OPTIONS`,
7132
+ carries the specific failure code (`VALIDATION_FAILED`,
6871
7133
  `REQUIRES_REENCODE`, `CYCLIC_WORKFLOW_EDGES`, …) while
6872
7134
  `error_type` only names the envelope shape.
6873
7135
  error:
6874
7136
  type: string
6875
- description: |
6876
- Stable error code. Common values: `INVALID_OPTIONS`
6877
- (generic option/value validation failure), `REQUIRES_REENCODE`
7137
+ x-string-vocabulary: open
7138
+ description: |
7139
+ Error code. **Each published code is stable; the SET is open**
7140
+ (`x-string-vocabulary: open`): handle an unknown code as a generic
7141
+ validation error. Codes emitted today: `VALIDATION_FAILED`
7142
+ (request, query-param **and workflow-create option/value**
7143
+ validation failure — the API emits it for every create-time
7144
+ option error: unknown key, out of range, wrong type, bad enum
7145
+ value; `details[]` items carry `field` = the option key and
7146
+ `message`), `REQUIRES_REENCODE`
6878
7147
  (per ticket I16-CONS — `merge.video` with
6879
7148
  `re_encode_mode: never` and incompatible inputs; caller
6880
7149
  resolves by switching to `re_encode_mode: auto` or `always`),
6881
7150
  `CYCLIC_WORKFLOW_EDGES` (cyclic/self explicit `workflow_edges`,
6882
- per `g8PPkbNu`), `VALIDATION_FAILED` (request/query-param
6883
- validation failure per the project-wide convention — e.g.
6884
- `GET /api/v2/credits/usage` invalid `limit`/`offset`).
7151
+ per `g8PPkbNu`).
7152
+ ⚠️ **`INVALID_OPTIONS` is NOT a create-time wire code**, though
7153
+ earlier text here said it was and the example showed it: the
7154
+ API has always sent `VALIDATION_FAILED` for option failures
7155
+ (measured on prod by `compression_e2e`, 2026-09-23;
7156
+ `WorkflowController` maps every `validation_error` to it).
7157
+ `invalid_options` lives on the worker's
7158
+ `OperationResult.error_code` (asyncapi), not on this envelope.
6885
7159
  SDKs duck-type on this field for typed error-branch helpers.
6886
7160
  message:
6887
7161
  type: string
@@ -6988,6 +7262,7 @@ components:
6988
7262
  enum: [false]
6989
7263
  error:
6990
7264
  type: string
7265
+ x-string-vocabulary: open
6991
7266
  description: |
6992
7267
  Stable machine-readable failure code. `UNPROCESSABLE_ENTITY`
6993
7268
  for the generic auth domain rejections (register /
@@ -7221,6 +7496,14 @@ components:
7221
7496
  PerMimeAvailability:
7222
7497
  type: object
7223
7498
  description: |
7499
+ **CLOSED TO NEW DECLARATIONS since 2026-09-18** ([`DquOfy7f`](https://trello.com/c/DquOfy7f)).
7500
+ Retained for compatibility only: no cell declares it, and
7501
+ `scripts/check-per-mime-availability.py` fails on any
7502
+ declaration. The API does not enforce it and the SDKs do not
7503
+ gate on it, so a differentiated MIME MUST use a parallel
7504
+ mime_group instead. The description below records what the
7505
+ field meant when it was open.
7506
+
7224
7507
  Map of MIME-type → `PerValueAvailabilityEntry`. Attached to a
7225
7508
  mime_group's `per_mime_availability` field when individual
7226
7509
  MIMEs within the same `mimes:` list ship at different
@@ -7240,8 +7523,9 @@ components:
7240
7523
  remains the right tool when the differentiated subset has
7241
7524
  materially different option shape (animated GIF
7242
7525
  watermarking, video-base watermarking, etc.). This
7243
- primitive is for pure availability differentiation within
7244
- an otherwise-homogeneous mime list.
7526
+ primitive WAS for pure availability differentiation within
7527
+ an otherwise-homogeneous mime list; since the closure above,
7528
+ that case uses a parallel mime_group too.
7245
7529
  additionalProperties:
7246
7530
  $ref: '#/components/schemas/PerValueAvailabilityEntry'
7247
7531
 
@@ -7891,6 +8175,32 @@ components:
7891
8175
  data:
7892
8176
  $ref: '#/components/schemas/AccountLimits'
7893
8177
 
8178
+ CheckoutSessionStatusResponse:
8179
+ type: object
8180
+ # Envelope CLOSED, payload OPEN — the repo's success-envelope convention:
8181
+ # top-level drift is detected, and new `data` fields stay additive.
8182
+ additionalProperties: false
8183
+ required: [success, data]
8184
+ properties:
8185
+ success:
8186
+ type: boolean
8187
+ enum: [true]
8188
+ data:
8189
+ type: object
8190
+ required: [session_id, status]
8191
+ properties:
8192
+ session_id:
8193
+ type: string
8194
+ description: Echo of the path parameter.
8195
+ status:
8196
+ type: string
8197
+ enum: [paid, pending, unknown]
8198
+ x-enum-openness: closed
8199
+ description: |
8200
+ `paid` / `pending` / `unknown` — see
8201
+ `GET /api/billing/checkout/{sessionId}/status`. `unknown`
8202
+ collapses "not yours" and "never existed" on purpose.
8203
+
7894
8204
  AccountLimits:
7895
8205
  type: object
7896
8206
  # Open payload (response data target stays open for additive evolution —
@@ -7951,6 +8261,29 @@ components:
7951
8261
  # api emits it. Unit is SECONDS — carried by the key name, per
7952
8262
  # AccountLimitEntry.
7953
8263
  $ref: '#/components/schemas/AccountLimitEntry'
8264
+ max_upload_image_pixels:
8265
+ # OPTIONAL in this expand step (ONxpaAlk); NOT required until api
8266
+ # emits it. The upload gate's pixel ceiling for decodable rasters
8267
+ # (width x height from the header) — the 413
8268
+ # IMAGE_DIMENSIONS_TOO_LARGE threshold. It is an ENV KNOB on the
8269
+ # API (UPLOAD_MAX_IMAGE_PIXELS), so the contract carries the
8270
+ # SHAPE and the server serves the NUMBER; a number written here
8271
+ # could drift from the running value by a task-definition edit.
8272
+ # Not tier-varying today: `tier_default` equals `effective`.
8273
+ # SINGLE-SHOT only (POST /api/uploads): sized for the API's inline
8274
+ # decode. Multipart has its own key below (ae4Q1yCb).
8275
+ $ref: '#/components/schemas/AccountLimitEntry'
8276
+ max_multipart_upload_image_pixels:
8277
+ # OPTIONAL in this expand step (ae4Q1yCb, owner ruling 2026-09-24);
8278
+ # NOT required until api emits it. The MULTIPART upload pixel
8279
+ # ceiling (width x height from the header) — the 413
8280
+ # IMAGE_DIMENSIONS_TOO_LARGE threshold on the multipart path. A
8281
+ # SEPARATE, HIGHER API setting than max_upload_image_pixels:
8282
+ # default 50 MP (hub, 2026-09-24), about half the workers'
8283
+ # declared 100 MP source cap, which is unproven end to end; it
8284
+ # rises only after a 100 MP staging proof. It MUST admit a 24 MP
8285
+ # photo. The server serves the number. Not tier-varying today.
8286
+ $ref: '#/components/schemas/AccountLimitEntry'
7954
8287
 
7955
8288
  AccountLimitEntry:
7956
8289
  type: object
@@ -8005,9 +8338,10 @@ components:
8005
8338
  description: |
8006
8339
  Single ledger entry. Immutable once written. A workflow-create
8007
8340
  reservation appears here as a single row with `source_bucket`
8008
- indicating which pool(s) were debited; refunds appear as
8009
- separate rows referencing the original via `reference_id` and
8010
- `reference_type: workflow`.
8341
+ indicating which pool(s) were debited; a returned reservation
8342
+ appears as a separate `reservation_release` row referencing the
8343
+ workflow via `reference_id` (see `reference_type` for the
8344
+ values that distinguish a release from a settle refund).
8011
8345
 
8012
8346
  `type`, `pricing_version`, and `reference_type` are
8013
8347
  deliberately free-form strings — their value sets evolve with
@@ -8036,11 +8370,16 @@ components:
8036
8370
  $ref: '#/components/schemas/UuidV7'
8037
8371
  type:
8038
8372
  type: string
8039
- description: |
8040
- Ledger entry type — free-form string. Common values:
8041
- `reservation`, `refund`, `top_up`, `monthly_grant`,
8042
- `adjustment`. Not enumerated to avoid contract churn as
8043
- billing event taxonomy evolves.
8373
+ x-string-vocabulary: open
8374
+ description: |
8375
+ Ledger entry type — free-form string. Values the API emits
8376
+ today (its `CreditTransactionType`, a closed set): `grant`,
8377
+ `deduction`, `adjustment`, `overdraft_repayment`,
8378
+ `reservation`, `reservation_release`. **There is no
8379
+ `refund`, `top_up` or `monthly_grant`** — earlier text listed
8380
+ them, and a consumer filtering on one matched nothing. Not
8381
+ enumerated in the schema to avoid contract churn as billing
8382
+ event taxonomy evolves; SDKs duck-type.
8044
8383
  amount:
8045
8384
  type: integer
8046
8385
  description: |
@@ -8104,6 +8443,7 @@ components:
8104
8443
  applies symmetrically.
8105
8444
  pricing_version:
8106
8445
  type: string
8446
+ x-string-vocabulary: none
8107
8447
  description: |
8108
8448
  Pricing-table version applied to this transaction.
8109
8449
  Free-form string (server emits a semver-shaped or
@@ -8117,10 +8457,16 @@ components:
8117
8457
  description: Human-readable description of the ledger entry.
8118
8458
  reference_type:
8119
8459
  type: string
8120
- description: |
8121
- What the transaction references. Common values:
8122
- `workflow`, `top_up`, `cycle_grant`, `adjustment`.
8123
- Free-form string.
8460
+ x-string-vocabulary: open
8461
+ description: |
8462
+ What the transaction references. Free-form string. Values
8463
+ the API emits for workflow credits: `workflow_reservation`
8464
+ (the debit), `workflow_reservation_release`,
8465
+ `workflow_pause_release`, `workflow_expiry_release` and
8466
+ `workflow_settle_refund` (credits returned);
8467
+ `stripe_checkout_session` for a credit-pack purchase. Match
8468
+ on this field, not on `type`, to tell a release from a
8469
+ settle refund.
8124
8470
  reference_id:
8125
8471
  type: string
8126
8472
  description: |
@@ -8178,6 +8524,7 @@ components:
8178
8524
  # additively from the API ahead of this contract.
8179
8525
  state:
8180
8526
  type: [string, "null"]
8527
+ x-string-vocabulary: open
8181
8528
  description: |
8182
8529
  Reservation lifecycle state — free-form string (kept opaque like
8183
8530
  `type`/`reference_type` for churn-resistance; SDKs duck-type).
@@ -8378,14 +8725,64 @@ components:
8378
8725
  format: uri
8379
8726
  description: Top-up deep link.
8380
8727
 
8728
+ SseConnectionLimitResponse:
8729
+ type: object
8730
+ description: |
8731
+ `429` body for `GET /api/workflows/{id}/events` when the caller already
8732
+ holds the maximum number of open event streams
8733
+ (`SSE_CONNECTION_LIMIT_EXCEEDED`). The limit, who counts as the caller,
8734
+ and the consumer obligation are on that response. Carries the two
8735
+ counts the SDK taxonomy's `metadataSchema` names (`openStreams` /
8736
+ `maxStreams` after camelCase lowering), so a client can say "5 of 5
8737
+ streams open" without restating the limit.
8738
+
8739
+ **Both count fields are REQUIRED when `error` is
8740
+ `SSE_CONNECTION_LIMIT_EXCEEDED` and absent otherwise**, enforced by the
8741
+ `if`/`then`/`else` branch below rather than a plain `required` list,
8742
+ because the endpoint's other `429` — `TOO_MANY_REQUESTS` from the
8743
+ start-rate limiter — is the plain `ErrorEnvelope` subset of this shape
8744
+ and must validate against it too.
8745
+ allOf:
8746
+ - $ref: '#/components/schemas/ErrorEnvelope'
8747
+ - type: object
8748
+ properties:
8749
+ open_streams:
8750
+ type: integer
8751
+ minimum: 0
8752
+ description: Streams this caller holds open at the moment of refusal.
8753
+ max_streams:
8754
+ type: integer
8755
+ minimum: 1
8756
+ description: |
8757
+ The caller's open-stream limit. **Read the limit from here,
8758
+ not from prose** — it is the server's value at refusal time.
8759
+ # The two 429 branches, machine-enforced (codex, #515 round 4): the
8760
+ # counts are REQUIRED on the stream-limit refusal and FORBIDDEN on any
8761
+ # other code (the start-rate limiter's plain TOO_MANY_REQUESTS).
8762
+ - if:
8763
+ required: [error]
8764
+ properties:
8765
+ error:
8766
+ const: SSE_CONNECTION_LIMIT_EXCEEDED
8767
+ then:
8768
+ required: [open_streams, max_streams]
8769
+ else:
8770
+ not:
8771
+ anyOf:
8772
+ - required: [open_streams]
8773
+ - required: [max_streams]
8774
+
8381
8775
  LongFormConcurrencyLimitResponse:
8382
8776
  type: object
8383
8777
  description: |
8384
8778
  `429` response body for `POST /api/workflows` when the caller
8385
8779
  already holds the maximum number of concurrent in-flight
8386
8780
  long-form (Fargate) workflows their tier permits
8387
- (`UserTier.maxConcurrentLongFormJobs`: Pro 2 / Max 5; Enterprise
8388
- + Free uncapped — Free has no long-form access at all). Carried
8781
+ (`UserTier.maxConcurrentLongFormJobs`, owned by the API and not
8782
+ restated here: an earlier copy said Free was uncapped and had no
8783
+ long-form access, while the API capped Free at a value of its own
8784
+ — and since 2026-09-23 every tier reaches long-form, decision 26,
8785
+ `jLuZvlJe`). Carried
8389
8786
  on a `429` but DISTINCT from an infrastructure rate-limit `429`:
8390
8787
 
8391
8788
  - `error` is the stable code `LONG_FORM_CONCURRENCY_LIMIT_EXCEEDED`
@@ -8439,10 +8836,11 @@ components:
8439
8836
  Effect of a workflow cancel on outstanding credit
8440
8837
  reservations.
8441
8838
  - `unspent_reservation_released`: caller refunded for the
8442
- unspent portion of the original reservation; refund
8443
- appears as a separate `CreditTransaction` (`type: refund`,
8444
- `reference_type: workflow`, `reference_id` matching the
8445
- cancelled workflow).
8839
+ unspent portion of the original reservation; the return
8840
+ appears as a separate `CreditTransaction` (`type:
8841
+ reservation_release`, `reference_type:
8842
+ workflow_reservation_release`, `reference_id` matching the
8843
+ cancelled workflow). There is no `type: refund`.
8446
8844
  - `none`: no refund issued (all reserved credits already
8447
8845
  consumed by completed jobs at cancel time, OR the
8448
8846
  workflow was already terminal in a previous cancel — the
@@ -9691,6 +10089,12 @@ components:
9691
10089
  OperationType:
9692
10090
  type: string
9693
10091
  description: |
10092
+ ⚠️ **HOMONYM:** `asyncapi/events.yaml` also declares an `OperationType` —
10093
+ the narrower event PAYLOAD vocabulary. This one is the CREATE surface.
10094
+ Same name, different membership; generated SDKs emit both, and the
10095
+ import path is the only distinguisher (not renamed — breaking;
10096
+ `bFy3zo5Y`). Relation asserted in `schemas/cross-document-enums.yaml`.
10097
+
9694
10098
  Available operation types:
9695
10099
  - compress: Reduce file size (images, audio, video, documents)
9696
10100
  - thumbnail: Legacy thumbnail value. Generates a preview image
@@ -9714,13 +10118,13 @@ components:
9714
10118
  - 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.
9715
10119
  - archive: Bundle files into ZIP/tar.gz (all types). Multi-input.
9716
10120
  - convert: Change file format (all types)
9717
- - 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).
10121
+ - 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` (no tier gate); 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).
9718
10122
  - 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).
9719
- - 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).
10123
+ - 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` (no tier gate since 2026-09-23); 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).
9720
10124
  - 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` — WITHDRAWN 2026-09-15: measured 0.300 s of encode per second of output PLUS A 7 s FIXED COST, so the advertised PT2H needs 2167 s against a 900 s platform maximum (0.300 x 7200 alone is 2160 — the intercept is what makes the figure 2167, and a consumer dividing 600 by 0.300 gets a 2000 s in-flight boundary where the real one is 1976 s). Returns `feature_not_available` (422) at workflow-create. An already-accepted workflow is not cancelled (availability is checked at create) and fails only when its output duration exceeds ~1976 s ON THE INPUT THE RATE WAS MEASURED WITH (a real photographic 1080p still plus looped real audio), where 0.300 s per second plus a 7 s fixed cost reaches the worker's 600 s cap — the 60 s and 120 s measured cells both COMPLETED. The driver is the STILL'S RESOLUTION, not duration alone: a 4K still is roughly 4x the rate (unmeasured), which would put the boundary near a quarter of that, and this schema places no constraint on the overlay's resolution. Per ticket [`SlluxMBN`](https://trello.com/c/SlluxMBN) + ADR-0015 (introduces `per_role_cardinality` vocab).
9721
10125
  - 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` — WITHDRAWN 2026-09-15, operation AND `short_form`: a real 1080p source at the advertised PT5M / 500 MB was killed at 606 s by the worker's 600 s encode cap, no output. Returns `feature_not_available` (422) at workflow-create; an already-accepted workflow is not cancelled and fails only if it exceeds that cap; the 606 s kill is ONE measured point and nothing measured says where the boundary is. `long_form` and `multi_overlay_stack` were already `planned`. Per ticket [`4NrRPCgh`](https://trello.com/c/4NrRPCgh) + ADR-0013.
9722
10126
  - 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` — WITHDRAWN 2026-09-15, operation AND `short_form`: a real 1080p source at the advertised PT5M was killed at 604 s by the worker's 600 s encode cap. Returns `feature_not_available` (422) at workflow-create. ⚠️ This entry previously read "until Lambda ships", which was wrong in a way that mattered: the worker SHIPPED and runs — it is the CEILING that cannot be served. Per ticket [`4NrRPCgh`](https://trello.com/c/4NrRPCgh) + ADR-0013.
9723
- - 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: beta` for the `audio` and `video` mime_groups (workers live on staging — shape-stable + opt-in, MUST NOT 422); video activates BOTH classes (`video.processing_class.short_form: beta` AND `long_form: beta` — `split-video-fargate` deployed + wired on staging but NOT yet proven end-to-end per [`rcwvUKhI`](https://trello.com/c/rcwvUKhI); the first customer-path soak has not completed, the 4GB+ speed-up is unmeasured, and the long-form fan-out is flag-gated dark). The `image_gif` and `document_pdf` mime_groups stay `availability: planned` and dispatch returns `feature_not_available` (422) until their workers ship. Per ticket [`vKI0CFDu`](https://trello.com/c/vKI0CFDu) + ADR-0014.
10127
+ - 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: beta` for the `audio` and `video` mime_groups (workers live on staging — shape-stable + opt-in, MUST NOT 422); video activates BOTH classes (`video.processing_class.short_form: beta` AND `long_form: beta` — `split-video-fargate` deployed + wired on staging; it stays `beta` until a PRODUCTION `customer_path` run is recorded in `availability/prod-verification-log.yaml` per [`rcwvUKhI`](https://trello.com/c/rcwvUKhI)). The `image_gif` and `document_pdf` mime_groups stay `availability: planned` and dispatch returns `feature_not_available` (422) until their workers ship. Per ticket [`vKI0CFDu`](https://trello.com/c/vKI0CFDu) + ADR-0014.
9724
10128
  - passthrough: Inert lossless source operation. A single-input source job whose SOLE operation is `passthrough` emits its source bytes UNCHANGED — no compression, no Lambda. The API self-completes the job at publish (terminal output = the upload `{bucket, key}` unchanged). Its purpose is to feed an uploaded file into a multi-input operation LOSSLESSLY: because `JobInputV2.source` is narrowed to exclude upload-direct, an upload that must enter a `merge` / `archive` / `image_watermark` op enters via a `passthrough` source job referenced downstream by `{type: job_output, from: <id>}` — preserving billing / DAG / lineage. Distinct from `operations: []` (which keeps its implicit-compress meaning on a single-input upload job); `passthrough` is the EXPLICIT lossless path via the "non-empty `operations[]` without `compress` = compression opt-out" rule. Media-agnostic; no options. `availability: beta` — activated (the inputs[]-narrowing + passthrough self-complete mechanism is deployed API-side); workflow-create accepts `passthrough` source jobs and MUST NOT return `feature_not_available`. **Never published to SNS** — deliberately absent from the AsyncAPI routing enums (API self-completes; no `ops-passthrough` queue). Per ticket [`4som89Uh`](https://trello.com/c/4som89Uh) + ADR-0004 (planned→beta flip).
9725
10129
 
9726
10130
  - transform: Geometric/orientation transform — v1 = rotate (0/90/180/270) + flip (none/horizontal/vertical/both), ADR-0026. Single-input; `produces: same_as_input` (geometry preserves format/container). Chainable (NOT sole_op); canonical single-job chain order is `transform → convert → compress → thumbnail` (geometry before encode/derive so downstream width/height/fit refer to the final frame). Media groups: image (still jpeg/png/webp + animated `image_gif`), video (mp4/webm), document (PDF page-rotate only — no flip); audio not supported. ALL groups `availability: planned` (epic `fhiWebI0`) — workflow-create returns `feature_not_available` (422) until per-media Lambdas ship. A no-op transform (`rotate: 0` + `flip: none`) is rejected as `invalid_options`. The public operation type is `transform`; the API resolves an internal per-media SNS routing sub-type (`transform_image` / `transform_video` / `transform_document`) — those sub-types are routing-only and are NOT part of this public enum. Per ADR-0026.
@@ -10608,13 +11012,9 @@ components:
10608
11012
  The two forms are mutually exclusive (a request supplies exactly
10609
11013
  one — enforced by the `oneOf` below); they are NOT combined.
10610
11014
 
10611
- 🔴 **THE FLAT FORM IS `planned`, AND THE SERVER DOES NOT ACCEPT IT
10612
- YET.** Send `jobs[]`. A flat request is rejected today, and the
10613
- rejection is currently a generic *"At least one job is required"*
10614
- rather than the `feature_not_available` (422) envelope this contract
10615
- requires for a `planned` shape — tracked against `compression_api`,
10616
- so do not read that generic message as a validation error in your
10617
- own payload.
11015
+ 🔴 **THE FLAT FORM IS `planned`.** Send `jobs[]`. A flat request is
11016
+ rejected with the `feature_not_available` (422) envelope (feature
11017
+ `workflow.request.flat_form`) until the API accepts the flat form.
10618
11018
 
10619
11019
  ⚠️ **The equivalence stated above is the DESIGN, not observed
10620
11020
  behaviour.** It describes what the server will do once the lowering
@@ -10770,11 +11170,12 @@ components:
10770
11170
  $ref: '#/components/schemas/NotifyConfig'
10771
11171
  description: |
10772
11172
  Optional per-job completion-notification config
10773
- (channel-agnostic). Currently exposes the `email` channel: the
10774
- API emails the configured recipients when the selected workflow
10775
- events occur, with a **server-composed** presigned `/downloads`
10776
- link to the results — the request carries recipients + event
10777
- selection only.
11173
+ (channel-agnostic). Declares the `email` channel: once the
11174
+ dispatch engine ships, the API emails the configured recipients
11175
+ when the selected workflow events occur, with a
11176
+ **server-composed** presigned `/downloads` link to the results —
11177
+ the request carries recipients + event selection only. Nothing is
11178
+ sent today (see `NotifyConfig`).
10778
11179
 
10779
11180
  **Advertised-ahead (contract-first, ticket
10780
11181
  [`IQtEwVET`](https://trello.com/c/IQtEwVET)):** the completion-
@@ -11316,6 +11717,7 @@ components:
11316
11717
  job that consumes this output.
11317
11718
  node_id:
11318
11719
  type: string
11720
+ x-string-vocabulary: open
11319
11721
  description: |
11320
11722
  Symbolic composition `node_id` correlating this delivered output
11321
11723
  to its canonical node in `composition_plan` (e.g. `encode`,
@@ -11607,6 +12009,7 @@ components:
11607
12009
  $ref: '#/components/schemas/ProcessingClass'
11608
12010
  execution_pool:
11609
12011
  type: string
12012
+ x-string-vocabulary: advisory
11610
12013
  description: |
11611
12014
  Logical pool name. **Opaque string** — not an enum — so
11612
12015
  future pool naming evolves without contract churn. Known
@@ -11870,6 +12273,7 @@ components:
11870
12273
  properties:
11871
12274
  node_id:
11872
12275
  type: string
12276
+ x-string-vocabulary: open
11873
12277
  description: |
11874
12278
  Stable **symbolic** canonical node id (e.g. `original`,
11875
12279
  `processed_base`, `encode`, `thumbnail`). The correlation key
@@ -11892,6 +12296,7 @@ components:
11892
12296
  nodes `type` is the operation as submitted.
11893
12297
  chain_group:
11894
12298
  type: string
12299
+ x-string-vocabulary: open
11895
12300
  description: |
11896
12301
  Which canonical stage this operation belongs to. **Open string,
11897
12302
  NOT a fixed enum** (mirrors `ProcessingPlanJob.execution_pool`) —
@@ -12018,9 +12423,10 @@ components:
12018
12423
  gating (per ticket I15-CONS) — reflects what the server
12019
12424
  would route this file to under the caller's current tier.
12020
12425
  `blocked` is emitted when no tier-permitted pool exists for
12021
- the file (e.g. free-tier caller probing a long-form clip,
12022
- or any caller probing a `corrupt` / `unsupported_codec`
12023
- file).
12426
+ the file — any caller probing a `corrupt` /
12427
+ `unsupported_codec` file, or a caller below a class's
12428
+ `required_tier`. Since 2026-09-23 (decision 26) no class
12429
+ carries one, so the tier branch is currently unreachable.
12024
12430
  # CLOSED. It GATES AN AFFORDANCE: `blocked` is a hard stop and the others
12025
12431
  # predict routing. An unrecognised class cannot be safely treated as routable —
12026
12432
  # a consumer guessing would offer an upload the server will refuse. A new
@@ -12601,7 +13007,9 @@ components:
12601
13007
  description: |
12602
13008
  OPTIONAL, drill-in-only "code for this run" / replay projection — the
12603
13009
  allowlisted, re-submittable shape of the original request (for an SDK
12604
- snippet / "run it again"). Absent until the API populates it. NOT a
13010
+ snippet / "run it again"). Emitted on every workflow status
13011
+ response by an API that implements the projector; OPTIONAL so a
13012
+ consumer of an older API build tolerates its absence. NOT a
12605
13013
  dump of the persisted option bag; see `CodegenSource`. Per ticket
12606
13014
  `LO0R5gzk`.
12607
13015
 
@@ -12836,8 +13244,9 @@ components:
12836
13244
  EXCLUDES all of that plus runtime results.
12837
13245
 
12838
13246
  **Detail-only** — `WorkflowStatusResponse` only, NEVER `WorkflowSummary`
12839
- (payload + the list view doesn't need it). OPTIONAL: the projector ships
12840
- incrementally; the field is absent until the API populates it.
13247
+ (payload + the list view doesn't need it). OPTIONAL in the schema so a
13248
+ consumer of an older API build tolerates its absence; an API that
13249
+ implements the projector emits it on every status response.
12841
13250
 
12842
13251
  **Scope: the reproducible JOB graph only.** Workflow-level request
12843
13252
  fields (`delivery` / `export` / `processing`) are deliberately NOT part
@@ -13248,6 +13657,9 @@ components:
13248
13657
  `never_started` (the operation was terminated without ever running
13249
13658
  because its job reached a terminal state first — an upstream failure
13250
13659
  OR a cancellation; API-derived, never worker-emitted),
13660
+ `processing_limit_exceeded` (a processing tool was killed at a
13661
+ budget set from this input — deterministic, non-retryable; a
13662
+ transient deadline is `timeout`),
13251
13663
  `unknown` (unclassified),
13252
13664
  `out_of_memory` (retryable), `timeout` (retryable),
13253
13665
  `s3_download_failed` (retryable), `s3_upload_failed` (retryable).
@@ -13258,6 +13670,39 @@ components:
13258
13670
  Human-readable failure detail. Present when `status` is `failed`;
13259
13671
  absent otherwise. Mirrors `SseOperationFailedData.error_message`.
13260
13672
  example: "output_too_large: Output (12156489 bytes) is not smaller than input (6187609 bytes)"
13673
+ message_key:
13674
+ $ref: '#/components/schemas/OperationMessageKey'
13675
+ message_params:
13676
+ $ref: '#/components/schemas/OperationMessageParams'
13677
+
13678
+ OperationMessageKey:
13679
+ type: string
13680
+ x-string-vocabulary: open
13681
+ pattern: '^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+$'
13682
+ description: |
13683
+ Stable, never-localised key REFINING `error_code` on a failed
13684
+ operation, so a client can show specific, localised copy (e.g.
13685
+ `thumbnail.epub.no_cover`). OPTIONAL, failed only. Every value is
13686
+ declared, with the codes it may accompany and its parameters, in
13687
+ `schemas/operation-message-keys.yaml` (the one registry). Passed
13688
+ through unchanged from the worker's OperationResult. A client
13689
+ that does not know a key, or receives one whose registry
13690
+ `error_codes` do not include this `error_code`, ignores the key and
13691
+ falls back to the `error_code` headline;
13692
+ retry is still decided from the code. Ticket U7GQhjhX.
13693
+ example: "thumbnail.epub.no_cover"
13694
+
13695
+ OperationMessageParams:
13696
+ type: object
13697
+ additionalProperties:
13698
+ type: [string, integer, number, boolean]
13699
+ description: |
13700
+ Interpolation values for `message_key`, named and typed in
13701
+ `schemas/operation-message-keys.yaml`. JSON scalars only (string,
13702
+ integer, number, boolean) — no nested objects. Absent when the key
13703
+ declares no parameters (`params: {}`), and carries exactly the
13704
+ registry's parameters otherwise. Never carries free-text
13705
+ diagnostics; those stay in `error_message`.
13261
13706
 
13262
13707
  OperationResultMetadata:
13263
13708
  type: object
@@ -13269,9 +13714,15 @@ components:
13269
13714
  diagnostics never leak. New keys are **additive named cuts** (the
13270
13715
  `additionalProperties: false` closure is the point — an unmodelled
13271
13716
  key is a coordinated contract change, not a silent rollout). Twin of
13272
- the AsyncAPI `OperationResultMetadata` (wire ↔ read parity). Distinct
13717
+ the AsyncAPI `OperationResultMetadata` (wire ↔ read parity), except
13718
+ `already_optimal` / `estimated_saving_pct`, which the API projects
13719
+ from the wire `OperationMetrics` where the worker emits them. Distinct
13273
13720
  from `OperationResult` (the deliverable output file): this carries
13274
13721
  small per-operation metadata, not the output. Per `EurbZLMH` (B1).
13722
+ # The estimated_saving_pct => already_optimal:true relation is ENFORCED on
13723
+ # the wire OperationMetrics this is projected from, not here: this schema
13724
+ # also types the workflowCallback webhook payload, where oasdiff reads an
13725
+ # added if/then as a breaking REQUEST change.
13275
13726
  properties:
13276
13727
  watermark_id:
13277
13728
  type: string
@@ -13284,6 +13735,28 @@ components:
13284
13735
  whitelist ship now (additive) so the result_metadata pipeline +
13285
13736
  read projection land without a later contract bump; absent in
13286
13737
  practice until B3 is live.
13738
+ already_optimal:
13739
+ type: boolean
13740
+ description: |
13741
+ `true` when the operation completed by returning the ORIGINAL file
13742
+ unchanged, because compressing it would not have made it smaller
13743
+ (or the source was already efficiently encoded). The operation is
13744
+ a success, not a failure: `result` is the original. Show it as
13745
+ "already optimised", not as "same size". On an ordinary result it
13746
+ is absent or `false`; treat the two the same. Projected by the API from the wire
13747
+ `OperationMetrics.already_optimal` (ticket `roNRMilt`).
13748
+ example: true
13749
+ estimated_saving_pct:
13750
+ type: number
13751
+ minimum: 0
13752
+ maximum: 100
13753
+ description: |
13754
+ OPTIONAL, only with `already_optimal: true`: the worker's ESTIMATE
13755
+ of how much smaller, as a percentage of the input size, a re-encode
13756
+ would have made the file, when it declined before encoding. Absent
13757
+ when no estimate was made. An estimate, not a guarantee. Projected
13758
+ from the wire `OperationMetrics.estimated_saving_pct`.
13759
+ example: 3.5
13287
13760
 
13288
13761
  OperationResult:
13289
13762
  type: object
@@ -13378,6 +13851,7 @@ components:
13378
13851
  `OperationMetrics.measured_quality`.
13379
13852
  quality_metric:
13380
13853
  type: string
13854
+ x-string-vocabulary: advisory
13381
13855
  description: |
13382
13856
  The perceptual metric that produced `measured_quality` — a free-form
13383
13857
  string (not an enum) so it can evolve without contract churn. Present
@@ -13394,6 +13868,7 @@ components:
13394
13868
  $ref: '#/components/schemas/ReEncodeDecision'
13395
13869
  re_encode_reason:
13396
13870
  type: string
13871
+ x-string-vocabulary: advisory
13397
13872
  description: |
13398
13873
  Advisory explanation for `re_encode_decision` (e.g.
13399
13874
  `all_inputs_compatible`, `explicit_always_mode`,
@@ -13688,6 +14163,7 @@ components:
13688
14163
  Mirrors `OperationMetrics.measured_quality`.
13689
14164
  quality_metric:
13690
14165
  type: string
14166
+ x-string-vocabulary: advisory
13691
14167
  description: |
13692
14168
  For an `auto_quality` encode: the perceptual metric that produced
13693
14169
  `measured_quality` — a free-form string (not an enum) so it can evolve
@@ -13736,6 +14212,7 @@ components:
13736
14212
  example: "thumb-2x"
13737
14213
  node_id:
13738
14214
  type: string
14215
+ x-string-vocabulary: open
13739
14216
  description: |
13740
14217
  Symbolic composition `node_id` correlating this download to its
13741
14218
  canonical node in `WorkflowCreateResponse.composition_plan` (e.g.
@@ -14119,9 +14596,10 @@ components:
14119
14596
  not: { required: [page_index] }
14120
14597
  - title: Unindexed
14121
14598
  description: |
14122
- Output without an explicit indexing field. Reserved for future
14123
- operations that index by something other than page/position.
14124
- Schema-valid but not currently emitted by any operation.
14599
+ Output without a page/position indexing field. Covers legacy
14600
+ single-output entries AND `render_variants` variant outputs (still
14601
+ `planned`, so not reachable through the API until that operation
14602
+ is). Mirrors the AsyncAPI `OperationResultOutputEntry` branch.
14125
14603
  not:
14126
14604
  anyOf:
14127
14605
  - required: [page_index]
@@ -14197,6 +14675,10 @@ components:
14197
14675
  generic reason.
14198
14676
  error_message:
14199
14677
  type: string
14678
+ message_key:
14679
+ $ref: '#/components/schemas/OperationMessageKey'
14680
+ message_params:
14681
+ $ref: '#/components/schemas/OperationMessageParams'
14200
14682
 
14201
14683
  SseJobCompletedData:
14202
14684
  type: object
@@ -14257,6 +14739,7 @@ components:
14257
14739
  - partially_failed
14258
14740
  reason:
14259
14741
  type: string
14742
+ x-string-vocabulary: advisory
14260
14743
  description: |
14261
14744
  Optional advisory reason for the terminal state. Free-form
14262
14745
  string; not an enum. Examples: "all jobs completed
@@ -15095,19 +15578,19 @@ components:
15095
15578
  description: |
15096
15579
  Operation-level availability tag. Optional — when absent, the
15097
15580
  operation is treated as `stable` (parser obligation per
15098
- ADR-0001 §1.4 / FORMAT.md §Availability Taxonomy). Runtime
15099
- emission lands with [I3 `eCWIpug8`](https://trello.com/c/eCWIpug8);
15100
- until then the contract declares the shape but the endpoint
15101
- does not yet surface the field.
15581
+ ADR-0001 §1.4 / FORMAT.md §Availability Taxonomy). Echoed by
15582
+ `GET /api/operations/schema` whenever the operation schema
15583
+ declares it ([I3 `eCWIpug8`](https://trello.com/c/eCWIpug8)).
15102
15584
  required_tier:
15103
15585
  $ref: '#/components/schemas/UserTier'
15104
15586
  description: |
15105
15587
  Operation-level minimum subscription tier. Optional — when
15106
15588
  absent, the operation is available to all callers regardless
15107
15589
  of tier. Per ADR-0001 §1.3 (tier and availability are
15108
- orthogonal axes). First operation-level consumer is
15590
+ orthogonal axes). First operation-level consumer was
15109
15591
  `custom_luma` (`required_tier: pro`) per
15110
- [I29 `EPUE5Vs1`](https://trello.com/c/EPUE5Vs1). SDK + frontend
15592
+ [I29 `EPUE5Vs1`](https://trello.com/c/EPUE5Vs1); that gate was
15593
+ dropped 2026-09-23 under decision 26 (owner ruling, `jLuZvlJe`). SDK + frontend
15111
15594
  consumers gate UI on this value alongside `availability` to
15112
15595
  hide higher-tier features for lower-tier callers; the
15113
15596
  runtime returns `feature_tier_restricted` (403) on
@@ -15228,18 +15711,31 @@ components:
15228
15711
  per_mime_availability:
15229
15712
  $ref: '#/components/schemas/PerMimeAvailability'
15230
15713
  description: |
15231
- Optional per-MIME availability map per ticket
15232
- [`YXYOo6gg`](https://trello.com/c/YXYOo6gg). Keys MUST be
15233
- a subset of `mimes[]` (CI-checked by
15234
- `scripts/check-per-mime-availability.py`); absent keys
15235
- default to `availability: stable`. Use this when
15236
- individual MIMEs within an otherwise-homogeneous mime
15237
- list ship at different availability levels (e.g.
15238
- `image/avif: beta, image/heic: planned` alongside
15239
- `image/jpeg: stable`). Runtime emission lands with
15240
- [I3](https://trello.com/c/eCWIpug8); until then the
15241
- contract advertises the field shape but the endpoint
15242
- does not yet surface the field.
15714
+ CLOSED TO NEW DECLARATIONS since 2026-09-18, ticket
15715
+ [`DquOfy7f`](https://trello.com/c/DquOfy7f). No mime_group
15716
+ declares this field and none may:
15717
+ `scripts/check-per-mime-availability.py` REFUSES any
15718
+ declaration, anywhere, at any depth. Expect this map to be
15719
+ absent or empty on every group.
15720
+
15721
+ USE A PARALLEL `mime_group` INSTEAD. A group-level
15722
+ `planned` is enforced at create by the API's 422 gate;
15723
+ this map is NOT enforced anywhere. `compression_api`
15724
+ round-trips it raw; the SDK generators parse and publish
15725
+ it but nothing gates on it (`sdk_exposure` composes
15726
+ op/group/option/value and has no per-MIME level); only the
15727
+ frontend UI resolves it. So a declared value would be
15728
+ served by the API, published to SDK consumers as metadata
15729
+ their own gating ignores, and honoured only in one UI.
15730
+
15731
+ The field itself is RETAINED, not removed: the shape is
15732
+ already published and deleting it would break the four
15733
+ consuming repos. Keys, if any were ever present, MUST be a
15734
+ subset of `mimes[]`, and absent keys mean
15735
+ `availability: stable`. Runtime emission was to land with
15736
+ [I3](https://trello.com/c/eCWIpug8); that roadmap is
15737
+ closed. See `schemas/FORMAT.md`
15738
+ §`per_mime_availability`.
15243
15739
  max_input_size_bytes:
15244
15740
  type: integer
15245
15741
  format: int64
@@ -15247,7 +15743,7 @@ components:
15247
15743
  description: |
15248
15744
  Optional mime-group-level INPUT-file size ceiling in BYTES
15249
15745
  (ticket [`uKsFzORi`](https://trello.com/c/uKsFzORi)). Sibling of
15250
- `max_output_pixels`. **Applies to the enclosing operation's input**, and
15746
+ `max_output_pixels` (declared below). **Applies to the enclosing operation's input**, and
15251
15747
  a consumer MUST scope it to the operation whose schema carries it —
15252
15748
  **the same MIME can carry different ceilings under different
15253
15749
  operations, because different workers process it.** ⚠️ This line
@@ -15270,6 +15766,33 @@ components:
15270
15766
  `processing_class.<class>.constraints.max_input_size_bytes` instead —
15271
15767
  never both, so the input ceiling lives in exactly one place per group.
15272
15768
  CI-enforced by `scripts/check-per-tier-constraints.py`.
15769
+ max_output_pixels:
15770
+ type: integer
15771
+ format: int64
15772
+ minimum: 1
15773
+ description: |
15774
+ Optional mime-group-level OUTPUT area cap: a request is valid on
15775
+ this axis iff `width × height <= max_output_pixels`, read from the
15776
+ two option values. Declared here since 2026-09-23 (`gACSVjiK`): it
15777
+ was named as a "sibling" of `max_input_size_bytes` while existing
15778
+ only in the operation schemas and the availability sidecar, and a
15779
+ consumer diffing the served schema reported it as a missing key.
15780
+ ⚠️ **Optional, and not yet round-tripped by `GET
15781
+ /api/operations/schema`** — the operation schemas under `schemas/`
15782
+ and `availability/availability.json` carry it today. See
15783
+ `schemas/FORMAT.md` §`max_output_pixels`.
15784
+ input_size_bound:
15785
+ type: string
15786
+ enum: [processing_time]
15787
+ x-enum-openness: closed
15788
+ description: |
15789
+ Declares that the group has **no byte ceiling on purpose**: the
15790
+ worker is bounded by processing time instead. XOR with
15791
+ `max_input_size_bytes` — exactly one is present when either is, so
15792
+ an absent pair means "nothing declared", never "unlimited".
15793
+ Declared here since 2026-09-23 (`gACSVjiK`) for the same reason as
15794
+ `max_output_pixels`, with the same round-trip caveat. See
15795
+ `schemas/FORMAT.md` §`input_size_bound`.
15273
15796
  max_input_duration:
15274
15797
  type: string
15275
15798
  description: |
@@ -15446,6 +15969,7 @@ components:
15446
15969
  description: Maximum value (for integer/float types)
15447
15970
  pattern:
15448
15971
  type: string
15972
+ x-string-vocabulary: none
15449
15973
  description: |
15450
15974
  ECMA-262 regular expression a `type: string` value MUST match
15451
15975
  (the string analogue of `min`/`max`). Consumers pre-validate
@@ -15456,6 +15980,29 @@ components:
15456
15980
  `#RRGGBB`; a CSS named colour was silently dropped to white). Only
15457
15981
  meaningful for `type: string`. See `schemas/FORMAT.md`.
15458
15982
  example: "^#[0-9a-fA-F]{6}$"
15983
+ items:
15984
+ type: object
15985
+ additionalProperties: true
15986
+ description: |
15987
+ `type: array` only. A JSON Schema 2020-12 OBJECT subschema every
15988
+ element must satisfy (boolean schemas are not used in this DSL;
15989
+ e.g. `{type: number, exclusiveMinimum: 0}` for
15990
+ `split.cut_points`, or an object shape for
15991
+ `image_watermark.overlays`). Named in JSON Schema's own camelCase,
15992
+ like `pattern`, because these ARE JSON Schema keywords and the
15993
+ published operation schemas already use them (fzrEO6GN).
15994
+ minItems:
15995
+ type: integer
15996
+ minimum: 0
15997
+ description: "`type: array` only. Fewest elements allowed."
15998
+ maxItems:
15999
+ type: integer
16000
+ minimum: 0
16001
+ description: "`type: array` only. Most elements allowed."
16002
+ uniqueItems:
16003
+ type: boolean
16004
+ description: |
16005
+ `type: array` only. `true`: elements must be pairwise distinct.
15459
16006
  depends_on:
15460
16007
  type: object
15461
16008
  description: |
@@ -15647,15 +16194,22 @@ components:
15647
16194
  NotifyConfig:
15648
16195
  type: object
15649
16196
  x-availability: planned
16197
+ # CLOSED to the declared channels: the API refuses an undeclared channel
16198
+ # key as validation_error, so the schema says so too (codex, #568).
16199
+ additionalProperties: false
15650
16200
  description: |
15651
16201
  Channel-agnostic per-job completion-notification config (ticket
15652
16202
  [`IQtEwVET`](https://trello.com/c/IQtEwVET)). Currently the `email`
15653
16203
  channel only; `webhook` folds onto the same dispatch engine later
15654
16204
  (today webhook is configured via the top-level `callback_url` /
15655
16205
  `callback_events`). **Advertised-ahead** — the API returns
15656
- `feature_not_available` (422) for any `notify` use until the
15657
- dispatch engine ships. `x-availability` is decorative per
15658
- ADR-0001 §1.5; the API is the authority on the 422 gate.
16206
+ `feature_not_available` (422) for any use of a declared channel
16207
+ until the dispatch engine ships, with feature path
16208
+ `workflow.notify.<channel>` (today `workflow.notify.email`), the
16209
+ same dotted grammar as `workflow.request.flat_form`. An undeclared
16210
+ channel key is a `validation_error` (422). `x-availability` is
16211
+ decorative per ADR-0001 §1.5; the API is the authority on the 422
16212
+ gate.
15659
16213
 
15660
16214
  An **empty `notify`** (object present but no channel set) is a
15661
16215
  no-op — the workflow runs normally with no notifications; it is