diff --git a/api.oas3.yaml b/api.oas3.yaml
index 9b144ff..d4b1f2a 100644
--- a/api.oas3.yaml
+++ b/api.oas3.yaml
@@ -23,8 +23,6 @@ info:
**[Ingest API](#shotstack-ingest)** - [https://api.shotstack.io/ingest/{version}](#)
Ingest (upload, store and transform) source footage, images, audio and fonts to be used by the Edit API.
- **[Create API](#shotstack-create)** - [https://api.shotstack.io/create/{version}](#)
- Generate images, videos, voice overs and text using built in and third party generative AI providers.
servers:
- url: https://api.shotstack.io/edit/{version}
@@ -54,15 +52,6 @@ servers:
- v1
- stage
default: v1
- - url: https://api.shotstack.io/create/{version}
- variables:
- version:
- description: >-
- Set the stage to **v1** for production usage. Set to **stage** to use the development sandbox.
- enum:
- - v1
- - stage
- default: v1
tags:
- name: Edit
@@ -84,14 +73,6 @@ tags:
API provides endpoints to fetch and upload files and check their status and URLs. All ingested files are available
directly from an S3 bucket URL or via CDN (Serve API).
- - name: Create
- description: >-
- The Create API generates assets and media files using Generative AI services like text-to-speech and
- text-to-avatar. A native text-to-speech service is included as well as integrations with third party providers.
- Third party services include [HeyGen](https://www.heygen.com/) text-to-avatar, [ElevenLabs](https://elevenlabs.io/)
- text-to-speech and [D-ID](https://www.d-id.com/) text-to-avatar. Assets can be used with the Edit API or
- downloaded and used independently.
-
paths:
/render:
$ref: "./paths/render.yaml"
@@ -129,15 +110,6 @@ paths:
/upload:
$ref: "./paths/upload.yaml"
- # Because of the way we have our servers set up and Create and Serve share the same endpoint name and how yaml/swagger
- # can't have duplicate keys - we use a temporary path name here /path_alias_createassets and rename it at built time
- # to assets using sed. Better ideas welcomed!
- /path_alias_createassets:
- $ref: "./paths/generateasset.yaml"
-
- # Using path alias and sed for replacement. See above comment.
- /path_alias_createassets/{id}:
- $ref: "./paths/generateassetid.yaml"
components:
schemas:
@@ -441,73 +413,6 @@ components:
Transfer:
$ref: "./schemas/serve/transfer.yaml#/Transfer"
- # Create schemas
- GeneratedAsset:
- $ref: "./schemas/create/generatedAsset.yaml#/GeneratedAsset"
-
- ShotstackGeneratedAsset:
- $ref: "./schemas/create/shotstackGeneratedAsset.yaml#/ShotstackGeneratedAsset"
-
- ShotstackGeneratedAssetOptions:
- $ref: "./schemas/create/shotstackGeneratedAssetOptions.yaml#/ShotstackGeneratedAssetOptions"
-
- ShotstackTextToSpeechOptions:
- $ref: "./schemas/create/shotstackTextToSpeechOptions.yaml#/ShotstackTextToSpeechOptions"
-
- ShotstackTextToImageOptions:
- $ref: "./schemas/create/shotstackTextToImageOptions.yaml#/ShotstackTextToImageOptions"
-
- ShotstackImageToVideoOptions:
- $ref: "./schemas/create/shotstackImageToVideoOptions.yaml#/ShotstackImageToVideoOptions"
-
- ShotstackTextGeneratorOptions:
- $ref: "./schemas/create/shotstackTextGeneratorOptions.yaml#/ShotstackTextGeneratorOptions"
-
- DIDGeneratedAsset:
- $ref: "./schemas/create/didGeneratedAsset.yaml#/DIDGeneratedAsset"
-
- DIDGeneratedAssetOptions:
- $ref: "./schemas/create/didGeneratedAssetOptions.yaml#/DIDGeneratedAssetOptions"
-
- DIDTextToAvatarOptions:
- $ref: "./schemas/create/didTextToAvatarOptions.yaml#/DIDTextToAvatarOptions"
-
- ElevenLabsGeneratedAsset:
- $ref: "./schemas/create/elevenlabsGeneratedAsset.yaml#/ElevenLabsGeneratedAsset"
-
- ElevenLabsGeneratedAssetOptions:
- $ref: "./schemas/create/elevenlabsGeneratedAssetOptions.yaml#/ElevenLabsGeneratedAssetOptions"
-
- ElevenLabsTextToSpeechOptions:
- $ref: "./schemas/create/elevenlabsTextToSpeechOptions.yaml#/ElevenLabsTextToSpeechOptions"
-
- HeyGenGeneratedAsset:
- $ref: "./schemas/create/heygenGeneratedAsset.yaml#/HeyGenGeneratedAsset"
-
- HeyGenGeneratedAssetOptions:
- $ref: "./schemas/create/heygenGeneratedAssetOptions.yaml#/HeyGenGeneratedAssetOptions"
-
- HeyGenTextToAvatarOptions:
- $ref: "./schemas/create/heygenTextToAvatarOptions.yaml#/HeyGenTextToAvatarOptions"
-
- OpenAiGeneratedAsset:
- $ref: "./schemas/create/openaiGeneratedAsset.yaml#/OpenAiGeneratedAsset"
-
- OpenAiGeneratedAssetOptions:
- $ref: "./schemas/create/openaiGeneratedAssetOptions.yaml#/OpenAiGeneratedAssetOptions"
-
- OpenAiTextGeneratorOptions:
- $ref: "./schemas/create/openaiTextGeneratorOptions.yaml#/OpenAiTextGeneratorOptions"
-
- StabilityAiGeneratedAsset:
- $ref: "./schemas/create/stabilityAiGeneratedAsset.yaml#/StabilityAiGeneratedAsset"
-
- StabilityAiGeneratedAssetOptions:
- $ref: "./schemas/create/stabilityAiGeneratedAssetOptions.yaml#/StabilityAiGeneratedAssetOptions"
-
- StabilityAiTextToImageOptions:
- $ref: "./schemas/create/stabilityAiTextToImageOptions.yaml#/StabilityAiTextToImageOptions"
-
# Edit response schemas
QueuedResponse:
$ref: "./schemas/responses/queuedresponse.yaml#/QueuedResponse"
@@ -607,22 +512,6 @@ components:
IngestErrorResponseData:
$ref: "./schemas/ingest/responses/ingesterrorresponsedata.yaml#/IngestErrorResponseData"
- # Create response schemas
- GeneratedAssetResponse:
- $ref: "./schemas/create/responses/generatedAssetResponse.yaml#/GeneratedAssetResponse"
-
- GeneratedAssetResponseData:
- $ref: "./schemas/create/responses/generatedAssetResponseData.yaml#/GeneratedAssetResponseData"
-
- GeneratedAssetResponseAttributes:
- $ref: "./schemas/create/responses/generatedAssetResponseAttributes.yaml#/GeneratedAssetResponseAttributes"
-
- GeneratedAssetErrorResponse:
- $ref: "./schemas/create/responses/generatedAssetErrorResponse.yaml#/GeneratedAssetErrorResponse"
-
- GeneratedAssetErrorResponseData:
- $ref: "./schemas/create/responses/generatedAssetErrorResponseData.yaml#/GeneratedAssetErrorResponseData"
-
responses: {}
parameters: {}
examples: {}
diff --git a/schemas/svgasset.yaml b/schemas/svgasset.yaml
index 39f9aeb..cd74343 100644
--- a/schemas/svgasset.yaml
+++ b/schemas/svgasset.yaml
@@ -1,50 +1,29 @@
SvgAsset:
description: |
- The SvgAsset is used to add scalable vector graphics (SVG) shapes to a video.
- It provides two mutually exclusive ways to define shapes:
+ The SvgAsset is used to add scalable vector graphics (SVG) to a video using raw SVG markup.
- **Option 1: Import SVG markup using `src`**
```json
{
"type": "svg",
"src": ""
}
```
- When using `src`, no other properties are allowed. The fill, stroke, and dimensions
- are automatically extracted from the SVG markup.
- **Option 2: Define shapes programmatically using `shape`**
- ```json
- {
- "type": "svg",
- "shape": { "type": "circle", "radius": 50 },
- "fill": { "type": "solid", "color": "#FF0000" }
- }
- ```
- When using `shape`, you can customize fill, stroke, shadow, transform, and other properties.
- The `src` property is not allowed in this mode.
-
- **Important:** You must provide either `src` OR `shape`, but not both.
- These two modes are mutually exclusive.
+ **Supported elements:** ``, ``, ``, ``,
+ ``, ``, ``
- **Available Shapes (Option 2 only):**
- - `rectangle` - Rectangles with optional rounded corners
- - `circle` - Perfect circles
- - `ellipse` - Ellipses/ovals with separate x and y radii
- - `line` - Straight lines with configurable thickness
- - `polygon` - Regular polygons (triangle, pentagon, hexagon, etc.)
- - `star` - Multi-pointed stars
- - `arrow` - Directional arrows
- - `heart` - Heart shapes
- - `cross` - Plus/cross shapes
- - `ring` - Donut/ring shapes
- - `path` - Custom shapes using SVG path data
+ **Automatically extracted from SVG markup:**
+ - Path data (converted to a single combined path)
+ - Fill color (from `fill` attribute or `style`)
+ - Stroke color and width (from attributes or `style`)
+ - Dimensions (from `width`/`height` or `viewBox`)
+ - Opacity (from `opacity` attribute)
See [W3C SVG 2 Specification](https://www.w3.org/TR/SVG2/) for path data syntax.
type: object
properties:
type:
- description: The asset type - set to `svg` for SVG shapes.
+ description: The asset type - set to `svg` for SVG assets.
type: string
enum:
- svg
@@ -52,123 +31,16 @@ SvgAsset:
example: svg
src:
description: |
- Raw SVG markup string to import. When provided, the shape is extracted
- automatically from the SVG content.
-
- **Supported elements:** ``, ``, ``, ``,
- ``, ``, ``
-
- **Automatically extracted:**
- - Path data (converted to a single combined path)
- - Fill color (from `fill` attribute or `style`)
- - Stroke color and width (from attributes or `style`)
- - Dimensions (from `width`/`height` or `viewBox`)
- - Opacity (from `opacity` attribute)
-
- **Important:** When using `src`, no other properties (shape, fill, stroke, etc.)
- are allowed. All styling must be defined within the SVG markup itself.
+ Raw SVG markup string. The shape, fill, stroke, dimensions and opacity
+ are automatically extracted from the SVG content.
type: string
minLength: 1
maxLength: 500000
example: ''
- shape:
- description: |
- The shape definition using primitives. The `type` property within determines
- the shape kind and its specific properties.
-
- **Important:** When using `shape`, the `src` property is not allowed.
- $ref: "./svgshapes.yaml#/SvgShape"
- fill:
- description: |
- Fill properties for the shape interior.
- Can be a solid color or a gradient (linear/radial).
- If omitted, the shape will have no fill (transparent interior).
-
- **Note:** Only allowed when using `shape`, not with `src`.
- $ref: "./svgproperties.yaml#/SvgFill"
- stroke:
- description: |
- Stroke (outline) properties for the shape.
- If omitted, the shape will have no stroke (no outline).
-
- **Note:** Only allowed when using `shape`, not with `src`.
- $ref: "./svgproperties.yaml#/SvgStroke"
- shadow:
- description: |
- Drop shadow properties for the shape.
- Creates a shadow effect behind the shape.
-
- **Note:** Only allowed when using `shape`, not with `src`.
- $ref: "./svgproperties.yaml#/SvgShadow"
- transform:
- description: |
- Transform properties for positioning, rotating, and scaling the shape.
- The transform is applied relative to the transformation origin.
-
- **Note:** Only allowed when using `shape`, not with `src`.
- $ref: "./svgproperties.yaml#/SvgTransform"
- opacity:
- description: |
- The overall opacity of the entire shape (including fill, stroke, and shadow).
- `1` is fully opaque, `0` is fully transparent.
- This is applied on top of individual fill/stroke/shadow opacity values.
-
- **Note:** Only allowed when using `shape`, not with `src`.
- type: number
- minimum: 0
- maximum: 1
- default: 1
- example: 1
- width:
- description: |
- The width of the bounding box in pixels.
- If specified, the shape may be scaled to fit within this width.
- If omitted, the shape uses its natural dimensions.
-
- **Note:** Only allowed when using `shape`, not with `src`.
- type: integer
- minimum: 1
- maximum: 4096
- example: 400
- height:
- description: |
- The height of the bounding box in pixels.
- If specified, the shape may be scaled to fit within this height.
- If omitted, the shape uses its natural dimensions.
-
- **Note:** Only allowed when using `shape`, not with `src`.
- type: integer
- minimum: 1
- maximum: 4096
- example: 300
additionalProperties: false
required:
- type
+ - src
example:
type: svg
- shape:
- type: star
- points: 5
- outerRadius: 100
- innerRadius: 50
- fill:
- type: linear
- angle: 45
- stops:
- - offset: 0
- color: "#FFD700"
- - offset: 1
- color: "#FF6B6B"
- opacity: 1
- stroke:
- color: "#2C3E50"
- width: 3
- opacity: 1
- lineCap: round
- lineJoin: round
- transform:
- x: 200
- y: 150
- rotation: 0
- scale: 1
- opacity: 1
+ src: ''
diff --git a/scripts/fix-discriminator.cjs b/scripts/fix-discriminator.cjs
index 6609bb9..853e74e 100644
--- a/scripts/fix-discriminator.cjs
+++ b/scripts/fix-discriminator.cjs
@@ -125,48 +125,8 @@ const svgAssetPattern =
// Note: Do NOT include z.preprocess here - the number coercion pass will add it
const svgAssetSuperRefine = `export const svgassetSvgAssetSchema = z.object({
type: z.enum(["svg"]),
- src: z.optional(z.string().min(1).max(500000)),
- shape: z.optional(svgshapesSvgShapeSchema),
- fill: z.optional(svgpropertiesSvgFillSchema),
- stroke: z.optional(svgpropertiesSvgStrokeSchema),
- shadow: z.optional(svgpropertiesSvgShadowSchema),
- transform: z.optional(svgpropertiesSvgTransformSchema),
- opacity: z.optional(z.number().gte(0).lte(1)).default(1),
- width: z.optional(z.number().int().gte(1).lte(4096)),
- height: z.optional(z.number().int().gte(1).lte(4096)),
-}).superRefine((data, ctx) => {
- const hasShape = data.shape !== undefined;
- const hasSrc = data.src !== undefined && data.src.trim() !== "";
-
- if (!hasShape && !hasSrc) {
- ctx.addIssue({
- code: z.ZodIssueCode.custom,
- message: "Either 'src' or 'shape' must be provided",
- path: [],
- });
- }
-
- if (hasShape && hasSrc) {
- ctx.addIssue({
- code: z.ZodIssueCode.custom,
- message: "Provide either 'src' or 'shape', not both",
- path: ["src"],
- });
- }
-
- if (hasSrc) {
- const disallowedProps = ["shape", "fill", "stroke", "shadow", "transform", "width", "height"];
- for (const prop of disallowedProps) {
- if (data[prop] !== undefined) {
- ctx.addIssue({
- code: z.ZodIssueCode.custom,
- message: \`'\${prop}' is not allowed when using 'src'. Only 'type' and 'src' are allowed in import mode\`,
- path: [prop],
- });
- }
- }
- }
-});`;
+ src: z.string().min(1).max(500000),
+}).strict();`;
if (svgAssetPattern.test(content)) {
content = content.replace(svgAssetPattern, svgAssetSuperRefine);
@@ -492,48 +452,8 @@ if (fs.existsSync(zodGenCjsPath)) {
// Note: Do NOT include z.preprocess here - the number coercion pass will add it
const cjsSvgAssetSuperRefine = `exports.svgassetSvgAssetSchema = zod_1.z.object({
type: zod_1.z.enum(["svg"]),
- src: zod_1.z.optional(zod_1.z.string().min(1).max(500000)),
- shape: zod_1.z.optional(exports.svgshapesSvgShapeSchema),
- fill: zod_1.z.optional(exports.svgpropertiesSvgFillSchema),
- stroke: zod_1.z.optional(exports.svgpropertiesSvgStrokeSchema),
- shadow: zod_1.z.optional(exports.svgpropertiesSvgShadowSchema),
- transform: zod_1.z.optional(exports.svgpropertiesSvgTransformSchema),
- opacity: zod_1.z.optional(zod_1.z.number().gte(0).lte(1)).default(1),
- width: zod_1.z.optional(zod_1.z.number().int().gte(1).lte(4096)),
- height: zod_1.z.optional(zod_1.z.number().int().gte(1).lte(4096)),
-}).superRefine((data, ctx) => {
- const hasShape = data.shape !== undefined;
- const hasSrc = data.src !== undefined && data.src.trim() !== "";
-
- if (!hasShape && !hasSrc) {
- ctx.addIssue({
- code: zod_1.z.ZodIssueCode.custom,
- message: "Either 'src' or 'shape' must be provided",
- path: [],
- });
- }
-
- if (hasShape && hasSrc) {
- ctx.addIssue({
- code: zod_1.z.ZodIssueCode.custom,
- message: "Provide either 'src' or 'shape', not both",
- path: ["src"],
- });
- }
-
- if (hasSrc) {
- const disallowedProps = ["shape", "fill", "stroke", "shadow", "transform", "width", "height"];
- for (const prop of disallowedProps) {
- if (data[prop] !== undefined) {
- ctx.addIssue({
- code: zod_1.z.ZodIssueCode.custom,
- message: "'" + prop + "' is not allowed when using 'src'. Only 'type' and 'src' are allowed in import mode",
- path: [prop],
- });
- }
- }
- }
-});`;
+ src: zod_1.z.string().min(1).max(500000),
+}).strict();`;
if (cjsSvgAssetPattern.test(cjsContent)) {
cjsContent = cjsContent.replace(cjsSvgAssetPattern, cjsSvgAssetSuperRefine);