# Introduction
Welcome to **ShortGenius**, the AI-powered platform for generating short, engaging content. This documentation is your guide to integrating ShortGenius's APIs into your own projects, whether you want to automatically create videos from custom scripts, design images with unique AI-generated prompts, or convert text into lifelike speech.
## What is ShortGenius?
ShortGenius is a suite of AI tools designed to help you:
* Generate attention-grabbing **short videos** with minimal effort
* Create **AI-driven images** to enrich your media or marketing campaigns
* Convert text to speech via **text-to-speech (TTS)** technology
* **Publish and schedule** content automatically across your connected channels
ShortGenius abstracts away the complexity of AI generation and handles all the heavy lifting so you can focus on your core product, marketing, or creative goals.
## Official SDKs
To make integration even easier, we provide official SDKs for popular programming languages:
TypeScript SDK
Full TypeScript support with type safety and IntelliSense
Install with your favorite package manager:
{% tabs %}
{% tab title="TypeScript/JavaScript" %}
```bash
npm install shortgenius
# or
yarn add shortgenius
```
{% endtab %}
{% tab title="Python" %}
```bash
pip install shortgenius
```
{% endtab %}
{% endtabs %}
## Key Features & Use Cases
ShortGenius is built for speed, creativity, and ease-of-use. Developers can:
1. **Generate short video scripts** automatically from topics, URLs, or even existing text.
2. **Create stunning images** with just a text prompt.
* Perfect for social media posts, blog headers, product images, and more.
3. **Automate text-to-speech** for dynamic voiceovers, announcements, or user-centric experiences.
4. **Schedule & publish** your videos to multiple social channels, from TikTok to YouTube, without leaving the ShortGenius ecosystem.
5. **Create entire video series** to deliver continuous, automated content at scale.
Common scenarios include:
* Bulk-creating educational or marketing content
* Summarizing web articles or breaking news into bite-sized videos
* Rapidly prototyping visual assets for design or marketing campaigns
* Generating "quiz" or "fun fact" style videos for engagement on social media
# Quickstart
Below are the basic steps to get started with the ShortGenius API:
{% stepper %}
{% step %}
**Sign Up & Retrieve API Token**
1. Sign up for a ShortGenius account at .
2. Go to the [API keys](https://shortgenius.com/developers/keys) page to retrieve your API token.
3. Keep this token secure! You'll use it for authenticating API calls.
{% endstep %}
{% step %}
**Test the Health Endpoint**
Let's ensure everything is up and running with the `/health` endpoint.
```bash
curl --request GET \
--url "https://shortgenius.com/api/v1/health"
```
**Expected Response**:
```json
{
"status": "ok"
}
```
{% endstep %}
{% step %}
**Make Your First Authorized Request**
Add your token to the Authorization header:
```bash
curl --request GET \
--url "https://shortgenius.com/api/v1/music/genres" \
--header "Authorization: Bearer YOUR_API_TOKEN"
```
If your token is valid, you'll receive a JSON list of available music genres:
```json
[
{
"name": "Classical",
"recommended_for_locales": [...]
},
...
]
```
{% endstep %}
{% endstepper %}
This quickstart is enough to prove your token works and that the API is reachable. In the next sections, we'll dive deeper into the available endpoints and show you how to create videos, images, audio, and more.
## SDK Quickstarts
For a more streamlined development experience, check out our official SDKs:
{% content-ref url="quickstart-typescript" %}
[quickstart-typescript](/api/shortgenius-api/quickstart-typescript)
{% endcontent-ref %}
{% content-ref url="quickstart-python" %}
[quickstart-python](/api/shortgenius-api/quickstart-python)
{% endcontent-ref %}
***
> **Next Steps**\
> Now that you've tested the waters, proceed to [Authentication & Essentials](/api/shortgenius-api/essentials).
# TypeScript Quickstart
Get up and running with the ShortGenius TypeScript SDK in minutes. This guide will walk you through installation, authentication, and making your first API calls using TypeScript.
## Prerequisites
* Node.js v16 or higher
* npm, yarn, pnpm, or bun package manager
* A ShortGenius API key (get one at )
## Installation
Install the ShortGenius TypeScript SDK using your preferred package manager:
{% tabs %}
{% tab title="npm" %}
```bash
npm install shortgenius
```
{% endtab %}
{% tab title="yarn" %}
```bash
yarn add shortgenius
```
{% endtab %}
{% tab title="pnpm" %}
```bash
pnpm add shortgenius
```
{% endtab %}
{% tab title="bun" %}
```bash
bun add shortgenius
```
{% endtab %}
{% endtabs %}
## Quick Start
{% stepper %}
{% step %}
**Initialize the Client**
Create a new ShortGenius client instance with your API key:
```typescript
import { ShortGenius } from 'shortgenius'
const client = new ShortGenius({
bearerAuth: 'YOUR_API_KEY' // or use process.env.SHORTGENIUS_BEARER_AUTH
})
```
{% hint style="info" %}
The SDK will automatically look for the `SHORTGENIUS_BEARER_AUTH` environment variable if you don't provide the API key explicitly.
{% endhint %}
{% endstep %}
{% step %}
**Test the Connection**
Verify your setup by checking the API health status:
```typescript
async function checkHealth() {
const status = await client.status.check()
console.log('API Status:', status) // { status: "ok" }
}
checkHealth()
```
{% endstep %}
{% step %}
**List Available Resources**
Get available music genres for your videos:
```typescript
async function listMusicGenres() {
const genres = await client.getMusicGenres()
console.log('Available genres:', genres)
// Get tracks for a specific genre
if (genres.length > 0) {
const tracks = await client.getMusic(genres[0].id)
console.log(`Tracks in ${genres[0].name}:`, tracks)
}
}
listMusicGenres()
```
{% endstep %}
{% step %}
**Draft Your First Video**
Create a video draft from a topic:
```typescript
async function draftVideo() {
const draft = await client.draftVideo({
topic: 'Benefits of Drinking Water',
duration: '120',
locale: 'en-US'
})
console.log('Draft created:', draft)
console.log(`Title: ${draft.title}`)
console.log(`Scenes: ${draft.scenes.length}`)
return draft
}
draftVideo()
```
{% endstep %}
{% step %}
**Create the Final Video**
Turn your draft into a rendered video:
```typescript
async function createVideo() {
// First, get your publishing connections
const connections = await client.getConnections()
// Get available voices
const voices = await client.getVoices({ locale: 'en-US' })
// Create the draft
const draft = await client.draftVideo({
topic: 'Benefits of Drinking Water',
duration: '120',
locale: 'en-US'
})
// Create the video
const video = await client.createVideo({
contentType: 'Custom',
locale: 'en-US',
connectionIds: [connections[0].id], // Use your first connection
title: draft.title,
caption: draft.caption,
scenes: draft.scenes,
voiceId: voices[0].id,
aspectRatio: '9:16' // 9:16 for vertical video
})
console.log('Video created:', video)
console.log(`Video ID: ${video.id}`)
console.log(`Status: ${video.publishingState}`)
}
createVideo()
```
{% endstep %}
{% endstepper %}
## Complete Example
Here's a complete example that ties everything together:
```typescript
import { ShortGenius } from 'shortgenius'
const client = new ShortGenius({
bearerAuth: process.env.SHORTGENIUS_BEARER_AUTH!
})
async function main() {
// 1. Check API status
const status = await client.status.check()
console.log('ā API is', status.status)
// 2. Get resources
const [connections, voices, genres] = await Promise.all([
client.getConnections(),
client.getVoices({ locale: 'en-US' }),
client.getMusicGenres()
])
console.log(`šŗ Found ${connections.length} publishing connections`)
console.log(`š¤ Found ${voices.length} voices`)
console.log(`šµ Found ${genres.length} music genres`)
// 3. Draft a video
const draft = await client.draftVideo({
topic: '5 Amazing Space Facts',
duration: '60',
locale: 'en-US'
})
console.log(`\nš Draft created: "${draft.title}"`)
console.log(` ${draft.scenes.length} scenes generated`)
// 4. Get soundtrack
const tracks = await client.getMusic(genres[0].name)
// 5. Create the video
const video = await client.createVideo({
contentType: 'Custom',
locale: 'en-US',
connectionIds: [connections[0].id],
title: draft.title,
caption: draft.caption,
scenes: draft.scenes,
voiceId: voices[0].id,
soundtrackId: tracks[0].id,
aspectRatio: '9:16'
})
console.log(`\nš¬ Video created!`)
console.log(` ID: ${video.id}`)
console.log(` Status: ${video.publishingState}`)
// 6. Check video status
const videoDetails = await client.getVideo(video.id)
console.log(` Publishing state: ${videoDetails.publishingState}`)
}
main()
```
## Error Handling
The SDK provides typed error responses. Here's how to handle common errors:
```typescript
import { ShortGenius } from 'shortgenius'
import { APIError, APIConnectionError } from 'shortgenius'
const client = new ShortGenius({
bearerAuth: 'YOUR_API_KEY'
})
async function safeApiCall() {
const result = await client.getVideo('invalid-id')
return result
}
```
## Configuration Options
### Custom Timeout
```typescript
const client = new ShortGenius({
bearerAuth: 'YOUR_API_KEY',
timeout: 60000 // 60 seconds
})
```
### Custom Base URL
```typescript
const client = new ShortGenius({
bearerAuth: 'YOUR_API_KEY',
serverURL: 'https://custom.shortgenius.com/api/v1'
})
```
### Retry Configuration
```typescript
const client = new ShortGenius({
bearerAuth: 'YOUR_API_KEY',
retryConfig: {
strategy: 'backoff',
backoff: {
initialInterval: 1000,
maxInterval: 60000,
exponent: 1.5,
maxElapsedTime: 300000
},
retryConnectionErrors: true
}
})
```
## TypeScript Support
The SDK is fully typed, providing excellent IDE support and type safety:
```typescript
import { ShortGenius } from 'shortgenius'
import type { components, operations } from 'shortgenius'
// All request/response types are available
type Video = components.Video
type DraftVideoRequest = operations.DraftVideoRequestBody
// The SDK provides full IntelliSense
const client = new ShortGenius({
bearerAuth: 'YOUR_API_KEY'
})
// TypeScript will enforce correct parameters
const draft = await client.draftVideo({
topic: 'Space Facts', // required
duration: '60', // required
locale: 'en-US' // optional
// TypeScript error if you add invalid fields
})
```
## Next Steps
Now that you're up and running with the TypeScript SDK:
* š Check out the [Video Generation Guide](/api/shortgenius-api/guides/video-generation) for advanced video creation
* šØ Learn about [Image Generation](/api/shortgenius-api/guides/image-generation) for custom visuals
* šµ Explore [Audio Generation](/api/shortgenius-api/guides/audio-generation) for text-to-speech
* šŗ Set up [Publishing Connections](/api/shortgenius-api/guides/publishing) for automatic distribution
* š View the [Full API Reference](/api/shortgenius-api/api-reference/editor/create-video)
***
> **Need Help?**\
> Join our [Discord community](https://discord.gg/shortgenius) or check out more examples in our [GitHub repository](https://github.com/shortgenius/examples).
# Python Quickstart
Get up and running with the ShortGenius Python SDK in minutes. This guide will walk you through installation, authentication, and making your first API calls using Python.
## Prerequisites
* Python 3.7 or higher
* pip package manager
* A ShortGenius API key (get one at )
## Installation
Install the ShortGenius Python SDK using pip:
```bash
pip install shortgenius
```
For development or to get the latest features:
```bash
pip install --upgrade shortgenius
```
## Quick Start
{% stepper %}
{% step %}
**Initialize the Client**
Create a new ShortGenius client instance with your API key:
```python
from shortgenius import Shortgenius
# Initialize with API key
client = Shortgenius(
api_key="YOUR_API_KEY" # or use os.environ.get("SHORTGENIUS_API_KEY")
)
```
{% hint style="info" %}
The SDK will automatically look for the `SHORTGENIUS_API_KEY` environment variable if you don't provide the API key explicitly.
{% endhint %}
{% endstep %}
{% step %}
**Test the Connection**
Verify your setup by checking the API health status:
```python
from shortgenius import Shortgenius
client = Shortgenius(api_key="YOUR_API_KEY")
# Check API health
status = client.health.check()
print(f"API Status: {status.status}") # Should print: API Status: ok
```
{% endstep %}
{% step %}
**List Available Resources**
Get available voices and check your credits:
```python
# List available voices
voices = client.audio.voices.list_voices(locale="en-US")
print(f"Found {len(voices)} voices")
for voice in voices[:3]: # Show first 3 voices
print(f" - {voice.name} ({voice.source})")
if voice.tags:
print(f" Gender: {voice.tags.gender}, Accent: {voice.tags.accent}")
# Check your credits
credits = client.credits.list()
print(f"Credits: {credits.balance.credits}")
```
{% endstep %}
{% step %}
**Create Images for Your Video**
Generate images that you can use in video creation:
```python
# List available image styles
styles = client.images.list_styles()
print(f"Found {len(styles)} image styles")
# Show first few styles
for style in styles[:3]:
print(f" - {style.name}: {style.prompt}")
# Create an image
try:
image = client.images.create(
prompt="A serene mountain landscape at sunset",
aspect_ratio="9:16",
wait_for_generation=True
)
print(f"\nImage created: {image.id}")
print(f"URL: {image.url}")
except Exception as e:
print(f"Image creation failed: {e}")
print("This might be due to insufficient credits")
```
{% endstep %}
{% step %}
**Generate Topics and Create a Video**
Generate video topics and create a video:
```python
# Get necessary resources
connections = client.connections.list()
voices = client.audio.voices.list_voices(locale="en-US")
if not connections:
print("Please set up a publishing connection first!")
exit()
# Generate video topics
topics = client.videos.generate_topics(
parent_topic="space exploration",
locale="en-US",
number_of_topics=3
)
print(f"Generated {len(topics)} video topics:")
for i, topic in enumerate(topics[:3], 1):
print(f" {i}. {topic}")
# Create a video with a topic
if topics:
video = client.videos.create(
topic=topics[0],
locale="en-US",
connection_ids=[connections[0].id],
voice_id=voices[0].id if voices else None,
aspect_ratio="9:16"
)
print(f"\nVideo created!")
print(f" ID: {video.id}")
print(f" Status: {video.publishing_state}")
```
{% endstep %}
{% endstepper %}
## Complete Example
Here's a complete example that ties everything together:
```python
import os
from shortgenius import Shortgenius
from shortgenius.types import APIError
def main():
# Initialize client
client = Shortgenius(
api_key=os.environ.get("SHORTGENIUS_API_KEY", "YOUR_API_KEY")
)
try:
# 1. Check API status
status = client.health.check()
print(f"ā API is {status.status}")
# 2. Get resources
connections = client.connections.list()
voices = client.audio.voices.list_voices(locale="en-US")
credits = client.credits.list()
print(f"šŗ Found {len(connections)} publishing connections")
print(f"š¤ Found {len(voices)} voices")
print(f"š° Credits: {credits.balance.credits}")
if not connections:
print("ā Please set up at least one publishing connection")
return
# 3. Generate video topics
print("\nš Generating video topics...")
topics = client.videos.generate_topics(
parent_topic="space exploration",
locale="en-US",
number_of_topics=3
)
print(f" Generated {len(topics)} topics:")
for i, topic in enumerate(topics, 1):
print(f" {i}. {topic}")
# 4. Create an image for the video
image = None
try:
image = client.images.create(
prompt="Space exploration scene with stars and planets",
aspect_ratio="9:16",
wait_for_generation=True
)
print(f"š¼ļø Created image: {image.id}")
except Exception as e:
print(f"ā ļø Image creation failed: {e}")
# 5. Create the video
print("\nš¬ Creating video...")
if topics:
video = client.videos.create(
topic=topics[0],
locale="en-US",
connection_ids=[connections[0].id],
voice_id=voices[0].id if voices else None,
aspect_ratio="9:16"
)
print(f" Video ID: {video.id}")
print(f" Status: {video.publishing_state}")
# 6. Check video status
video_details = client.videos.retrieve(video.id)
print(f" Publishing state: {video_details.publishing_state}")
else:
print(" No topics generated")
except APIError as e:
print(f"ā API Error: {e.message}")
print(f" Status code: {e.status_code}")
except Exception as e:
print(f"ā Unexpected error: {e}")
if __name__ == "__main__":
main()
```
## Error Handling
The SDK provides comprehensive error handling with typed exceptions:
```python
from shortgenius import Shortgenius
from shortgenius.types import (
APIError,
APIConnectionError,
AuthenticationError,
RateLimitError,
NotFoundError
)
client = Shortgenius(api_key="YOUR_API_KEY")
try:
video = client.videos.retrieve("invalid-id")
except AuthenticationError:
print("Invalid API key")
except NotFoundError:
print("Video not found")
except RateLimitError as e:
print(f"Rate limit exceeded. Retry after: {e.retry_after}")
except APIConnectionError:
print("Network connection error")
except APIError as e:
print(f"API error {e.status_code}: {e.message}")
```
## Async Support
The SDK also provides an async client for better performance in async applications:
```python
import asyncio
from shortgenius import AsyncShortgenius
async def main():
# Initialize async client
async with AsyncShortgenius(api_key="YOUR_API_KEY") as client:
# All methods are now async
status = await client.health.check()
print(f"API Status: {status.status}")
# Concurrent requests
voices_task = client.audio.voices.list_voices(locale="en-US")
credits_task = client.credits.list()
voices, credits = await asyncio.gather(voices_task, credits_task)
print(f"Found {len(voices)} voices and {credits.balance.credits} credits")
# Run the async function
asyncio.run(main())
```
## Working with Different Content Types
### Working with Images
```python
# List available image styles
styles = client.images.list_styles()
print(f"Found {len(styles)} styles")
# Create an image with a specific style
cyberpunk_style = next((s for s in styles if "cyberpunk" in s.name.lower()), None)
if cyberpunk_style:
image = client.images.create(
prompt="A futuristic robot",
aspect_ratio="9:16",
image_style_id=cyberpunk_style.id,
wait_for_generation=True
)
print(f"Styled image created: {image.id}")
# List your created images
response = client.images.list(page=0, limit=10)
for img in response.images:
print(f"- {img.prompt}: {img.state}")
```
### Working with Audio
```python
# List available voices
voices = client.audio.voices.list_voices(locale="en-US")
for voice in voices:
print(f"- {voice.name} ({voice.source})")
if voice.tags:
print(f" Gender: {voice.tags.gender}, Accent: {voice.tags.accent}")
# Get details for a specific voice
if voices:
voice_details = client.audio.voices.retrieve_voice(voices[0].id)
print(f"Voice details: {voice_details.name}")
if voice_details.preview_url:
print(f"Preview: {voice_details.preview_url}")
# Create speech from text
speech = client.audio.create_speech(
text="Hello, this is a test of the speech generation system.",
voice_id=voices[0].id if voices else None,
locale="en-US",
wait_for_generation=True
)
print(f"Speech created: {speech.id}")
```
### Working with Video Series
```python
# Create a video series
series = client.series.create(
name="AI Technology Explained",
description="A series explaining artificial intelligence concepts"
)
print(f"Series created: {series.id}")
# List your series
series_list = client.series.list()
for s in series_list:
print(f"- {s.name}: {s.description}")
```
## Configuration Options
### Custom Timeout
```python
client = Shortgenius(
api_key="YOUR_API_KEY",
timeout=60.0 # 60 seconds
)
```
### Custom Base URL
```python
client = Shortgenius(
api_key="YOUR_API_KEY",
base_url="https://custom.shortgenius.com/api/v1"
)
```
### Retry Configuration
```python
client = Shortgenius(
api_key="YOUR_API_KEY",
max_retries=3 # Retry failed requests up to 3 times
)
```
### Using Proxies
```python
import httpx
client = Shortgenius(
api_key="YOUR_API_KEY",
http_client=httpx.Client(
proxies="http://proxy.example.com:8080"
)
)
```
## Working with Responses
All SDK methods return typed response objects:
```python
# Video object attributes
video = client.videos.retrieve(video_id)
print(f"ID: {video.id}")
print(f"Title: {video.title}")
print(f"Caption: {video.caption}")
print(f"Created: {video.created_at}")
print(f"Status: {video.publishing_state}")
# Iterate through paginated results
page = 0
while True:
response = client.videos.list(page=page, limit=50)
for video in response.videos:
print(f"- {video.title} ({video.id})")
if not response.has_more:
break
page += 1
```
## Best Practices
1. **Environment Variables**: Store your API key in environment variables:
```python
import os
client = Shortgenius(api_key=os.environ["SHORTGENIUS_API_KEY"])
```
2. **Error Handling**: Always wrap API calls in try-except blocks
3. **Rate Limiting**: Implement exponential backoff for rate limit errors
4. **Resource Cleanup**: Use context managers with async client
5. **Logging**: Enable debug logging for troubleshooting:
```python
import logging
logging.basicConfig(level=logging.DEBUG)
```
## Next Steps
Now that you're up and running with the Python SDK:
* š Check out the [Video Generation Guide](/api/shortgenius-api/guides/video-generation) for advanced video creation
* šØ Learn about [Image Generation](/api/shortgenius-api/guides/image-generation) for custom visuals
* šµ Explore [Audio Generation](/api/shortgenius-api/guides/audio-generation) for text-to-speech
* šŗ Set up [Publishing Connections](/api/shortgenius-api/guides/publishing) for automatic distribution
* š View the [Full API Reference](/api/shortgenius-api/api-reference/editor/create-video)
***
> **Need Help?**\
> Join our [Discord community](https://discord.gg/shortgenius) or check out more examples in our [GitHub repository](https://github.com/shortgenius/python-examples).
# Authentication & Essentials
In this section, we'll discuss how to securely authorize your requests, handle potential errors, and manage credits for ShortGenius services.
## Authentication (Bearer Token)
All ShortGenius endpoints require a valid **bearer token**. If you haven't already retrieved a token from your [ShortGenius dashboard](https://shortgenius.com), follow the sign-up process mentioned in our [Getting Started Quickstart](/api/shortgenius-api/essentials).
### Using cURL
**How to include your token:**
```
Authorization: Bearer YOUR_API_TOKEN
```
**Example request:**
```bash
curl --request GET \
--url "https://shortgenius.com/api/v1/health" \
--header "Authorization: Bearer YOUR_API_TOKEN"
```
### Using SDKs
If you're using one of our official SDKs, authentication is even simpler:
{% tabs %}
{% tab title="TypeScript" %}
```typescript
import { ShortGenius } from 'shortgenius'
const client = new ShortGenius({
bearerAuth: 'YOUR_API_TOKEN'
})
// The SDK automatically includes the bearer token in all requests
const status = await client.status.check()
```
You can also use environment variables:
```typescript
// SDK will automatically use SHORTGENIUS_BEARER_AUTH env variable
const client = new ShortGenius({
bearerAuth: process.env.SHORTGENIUS_BEARER_AUTH
})
```
{% endtab %}
{% tab title="Python" %}
```python
from shortgenius import Shortgenius
client = Shortgenius(api_key="YOUR_API_TOKEN")
// The SDK automatically includes the API key in all requests
status = client.status.check()
```
You can also use environment variables:
```python
import os
// SDK will automatically use SHORTGENIUS_API_KEY env variable
client = Shortgenius(
api_key=os.environ.get("SHORTGENIUS_API_KEY")
)
```
{% endtab %}
{% endtabs %}
{% hint style="info" %}
**Tip**: Always store tokens securely (e.g., environment variables, secret managers). Do not commit them to version control.
{% endhint %}
## Handling Errors
ShortGenius will return standard HTTP status codes and JSON-encoded error messages when something goes wrong. Below are some common error types:
| Status Code | Meaning | Example Message |
| ----------- | --------------------- | ------------------------------------- |
| **400** | Bad Request | `{"message": "Invalid request"}` |
| **401** | Unauthorized | `{"message": "Unauthorized"}` |
| **404** | Not Found | `{"message": "Not found"}` |
| **429** | Too Many Requests | `{"message": "Rate limit exceeded"}` |
| **500** | Internal Server Error | `{"message": "Something went wrong"}` |
**Example of a 400 Response:**
```json
{
"message": "Invalid request"
}
```
### SDK Error Handling
The SDKs provide typed error handling:
{% tabs %}
{% tab title="TypeScript" %}
```typescript
import { ShortGenius, APIError } from 'shortgenius'
const client = new ShortGenius({ bearerAuth: 'YOUR_API_TOKEN' })
const video = await client.getVideo('invalid-id')
```
{% endtab %}
{% tab title="Python" %}
```python
from shortgenius import Shortgenius
from shortgenius.types import APIError
client = Shortgenius(api_key="YOUR_API_TOKEN")
try:
video = client.videos.retrieve("invalid-id")
except APIError as e:
print(f"API Error {e.status_code}: {e.message}")
if e.status_code == 401:
print("Check your API key")
elif e.status_code == 404:
print("Video not found")
elif e.status_code == 429:
print("Rate limit exceeded, slow down")
```
{% endtab %}
{% endtabs %}
Always inspect the returned JSON for more details on why a request failed.
## Rate Limits & Credits
ShortGenius enforces usage limits via a **credit-based system**. Each time you generate a video, image, or audio file, credits are deducted from your account.
**Types of credits include:**
* `credits` ā General-purpose for many actions
* `high_quality_video_credits` ā For higher resolution or advanced video rendering
### Checking Your Credit Balance
Use the **GET** `/credits` endpoint to see how many credits remain:
{% tabs %}
{% tab title="TypeScript" %}
```typescript
const usage = await client.getUsage()
console.log('Credit Balance:')
console.log(` General credits: ${usage.balance.credits}`)
console.log(` High quality video credits: ${usage.balance.high_quality_video_credits}`)
```
{% endtab %}
{% tab title="Python" %}
```python
usage = client.usage.get()
print("Credit Balance:")
print(f" General credits: {usage.balance.credits}")
print(f" High quality video credits: {usage.balance.high_quality_video_credits}")
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request GET \
--url "https://shortgenius.com/api/v1/credits" \
--header "Authorization: Bearer YOUR_API_TOKEN"
```
{% endtab %}
{% endtabs %}
{% hint style="info" %}
**Best Practice**: Check your available credits regularly to avoid interruptions, especially before generating large batches of videos or images.
{% endhint %}
***
> **Next Steps**\
> You're now ready to dig into ShortGenius's core functionality. Let's move on to [Video Generation](/api/shortgenius-api/guides/video-generation) to learn how to create short AI-driven clips from scratch.
# Video Generation
ShortGenius excels at transforming a simple prompt, URL, or script into a fully produced video complete with AI-generated narration and images. This section outlines the step-by-step process to create, list, and retrieve videos.
## Drafting Videos
Before creating a final video, you'll typically **draft** one or more scripts. These drafts return structured "scenes" that you can review or modify.
### 1. Draft a Video
**Endpoint**: `POST /videos/drafts`
Use this when you want to generate a video script from a single **topic**. For example:
{% tabs %}
{% tab title="TypeScript" %}
```typescript
import { ShortGenius } from 'shortgenius'
const client = new ShortGenius({
bearerAuth: 'YOUR_API_TOKEN'
})
const draft = await client.draftVideo({
topic: 'Benefits of Drinking Water',
duration: '120',
locale: 'en-US'
})
console.log(draft)
```
{% endtab %}
{% tab title="Python" %}
```python
from shortgenius import Shortgenius
client = Shortgenius(api_key="YOUR_API_TOKEN")
# Generate video topics first
topics = client.videos.generate_topics(
parent_topic="health and wellness",
locale="en-US",
number_of_topics=3
)
# Use the first topic for our example
topic = topics[0] if topics else "Benefits of Drinking Water"
print(draft)
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request POST \
--url "https://shortgenius.com/api/v1/videos/drafts" \
--header "Authorization: Bearer YOUR_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"topic": "Benefits of Drinking Water",
"duration": "120",
"locale": "en-US"
}'
```
{% endtab %}
{% endtabs %}
**Request Body Fields**:
| Field | Type | Required | Description |
| ---------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------- |
| `topic` | string | Yes | The topic you want to generate a script about. |
| `duration` | string | Yes | Desired duration in **seconds** (e.g., "60", "120"). This is best-effort only; verify you have enough credits. |
| `locale` | string | No | Language locale (default `"auto"`). |
**Sample Response**:
```json
{
"title": "Top Reasons to Drink More Water",
"caption": "Stay hydrated daily for better health and energy.",
"scenes": [
{
"title": null,
"caption": "Did you know that most people are chronically dehydrated?",
"first_image_description": "A glass of water with ice cubes",
"second_image_description": "A person feeling tired from dehydration"
},
...
]
}
```
### 2. Draft a Video from a URL
**Endpoint**: `POST /videos/drafts/url`
Use this to fetch textual content from a given **webpage** and transform it into a video script.
{% tabs %}
{% tab title="TypeScript" %}
```typescript
const draft = await client.draftVideoFromURL({
url: 'https://en.wikipedia.org/wiki/Water',
prompt: 'Focus on health benefits only',
locale: 'en-US'
})
```
{% endtab %}
{% tab title="Python" %}
```python
# Note: URL-based drafting may not be available in current SDK version
# Generate topics as alternative approach
topics = client.videos.generate_topics(
parent_topic="water benefits",
locale="en-US",
number_of_topics=1
)
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request POST \
--url "https://shortgenius.com/api/v1/videos/drafts/url" \
--header "Authorization: Bearer YOUR_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"url": "https://en.wikipedia.org/wiki/Water",
"prompt": "Focus on health benefits only",
"locale": "en-US"
}'
```
{% endtab %}
{% endtabs %}
### 3. Draft a Video from an Existing Script
**Endpoint**: `POST /videos/drafts/script`
If you already have a script written, ShortGenius can split it into logical scenes:
{% tabs %}
{% tab title="TypeScript" %}
```typescript
const draft = await client.draftVideoFromScript({
script: 'Water is essential for all living organisms...',
locale: 'en-US'
})
```
{% endtab %}
{% tab title="Python" %}
```python
# Note: Script-based drafting may not be available in current SDK version
# Use topic generation instead
topics = client.videos.generate_topics(
parent_topic="water science",
locale="en-US",
number_of_topics=1
)
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request POST \
--url "https://shortgenius.com/api/v1/videos/drafts/script" \
--header "Authorization: Bearer YOUR_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"script": "Water is essential for all living organisms...",
"locale": "en-US"
}'
```
{% endtab %}
{% endtabs %}
### 4. Draft a Quiz Video
**Endpoint**: `POST /videos/drafts/quiz`
Easily generate quiz-style content, complete with questions, multiple-choice answers, and a results explanation at the end.
{% tabs %}
{% tab title="TypeScript" %}
```typescript
const quiz = await client.draftQuizVideo({
topic: 'Hydration Facts',
locale: 'en-US'
})
```
{% endtab %}
{% tab title="Python" %}
```python
# Note: Quiz drafting may not be available in current SDK version
# Use topic generation for quiz-style content
topics = client.videos.generate_topics(
parent_topic="hydration quiz facts",
locale="en-US",
number_of_topics=1
)
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request POST \
--url "https://shortgenius.com/api/v1/videos/drafts/quiz" \
--header "Authorization: Bearer YOUR_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"topic": "Hydration Facts",
"locale": "en-US"
}'
```
{% endtab %}
{% endtabs %}
### 5. Draft a News Video
**Endpoint**: `POST /videos/drafts/news`
ShortGenius can gather recent headlines and generate a short news-style video for a given topic.
{% tabs %}
{% tab title="TypeScript" %}
```typescript
const news = await client.draftNewsVideo({
topic: 'Latest Tech News',
locale: 'en-US'
})
```
{% endtab %}
{% tab title="Python" %}
```python
# Note: News drafting may not be available in current SDK version
# Use topic generation for news-style content
topics = client.videos.generate_topics(
parent_topic="technology news",
locale="en-US",
number_of_topics=1
)
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request POST \
--url "https://shortgenius.com/api/v1/videos/drafts/news" \
--header "Authorization: Bearer YOUR_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"topic": "Latest Tech News",
"locale": "en-US"
}'
```
{% endtab %}
{% endtabs %}
***
## Creating the Final Video
Once you have a **draft** object (containing scenes or quiz data), you can pass it to the `/videos` endpoint to produce the final video file.
**Endpoint**: `POST /videos`
{% tabs %}
{% tab title="TypeScript" %}
```typescript
// Get required resources
const connections = await client.getConnections()
const voices = await client.getVoices({ locale: 'en-US' })
const genres = await client.getMusicGenres()
const tracks = await client.getMusic(genres[0].name)
// Create the video
const video = await client.createVideo({
contentType: 'Custom',
locale: 'en-US',
connectionIds: [connections[0].id],
aspectRatio: '9:16',
voicePlaybackRate: 100,
voiceVolume: 100,
soundtrackPlaybackRate: 100,
soundtrackVolume: 100,
title: 'All About Water',
caption: 'Learn fun facts about water consumption!',
scenes: draft.scenes, // Use scenes from your draft
voiceId: voices[0].id,
soundtrackId: tracks[0].id,
publishAt: '2025-05-01T10:00:00Z'
})
console.log(`Video created: ${video.id}`)
```
{% endtab %}
{% tab title="Python" %}
```python
# Get required resources
connections = client.connections.list()
voices = client.audio.voices.list_voices(locale="en-US")
# Generate a topic first
topics = client.videos.generate_topics(
parent_topic="water health benefits",
locale="en-US",
number_of_topics=1
)
# Create the video using a topic
video = client.videos.create(
topic=topics[0] if topics else "Benefits of Drinking Water",
locale="en-US",
connection_ids=[connections[0].id],
aspect_ratio="9:16",
voice_id=voices[0].id if voices else None
)
print(f"Video created: {video.id}")
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request POST \
--url "https://shortgenius.com/api/v1/videos" \
--header "Authorization: Bearer YOUR_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"content_type": "Custom",
"locale": "en-US",
"connection_ids": [""],
"aspect_ratio": "9:16",
"voice_playback_rate": 100,
"voice_volume": 100,
"soundtrack_playback_rate": 100,
"soundtrack_volume": 100,
"title": "All About Water",
"caption": "Learn fun facts about water consumption!",
"scenes": [
{
"title": null,
"caption": "Most people need at least 2 liters a day.",
"first_image_description": "Close-up shot of a water bottle",
"second_image_description": "Animated water droplets"
},
...
],
"voice_id": "",
"soundtrack_id": "",
"publish_at": "2025-05-01T10:00:00Z"
}'
```
{% endtab %}
{% endtabs %}
**Key Fields**:
| Field | Required | Description |
| ---------------- | ----------------------------------------------------- | ------------------------------------------------------------------- |
| `content_type` | No | `"Custom"`, `"News"`, `"Quiz"`, etc. |
| `locale` | No | `"en-US"`, `"auto"`, etc. |
| `connection_ids` | Yes | Array of **publishing connections** (get them from `/connections`). |
| `title` | Yes | Title of the final video. |
| `caption` | Yes | Caption/description to be displayed or posted with the video. |
| `scenes` |
Conditional (required if not quiz)
| The array of scenes from your draft. |
| `quiz` |
Conditional (required if quiz)
| Quiz content for quiz videos. |
| `voice_id` | No | ID of the voice for narration (from `/audio/voices`). |
| `soundtrack_id` | No | ID of the chosen soundtrack (from `/music/genres/{id}`). |
| `aspect_ratio` | No | `"9:16"`, `"16:9"`, `"1:1"`, etc. |
| `publish_at` | No | ISO 8601 date to schedule the video's publication. |
**Sample Successful Response**:
```json
{
"id": "98e19721-8b1e-45a8-abc2-555c7a6cd75d",
"title": "All About Water",
"caption": "Learn fun facts about water consumption!",
"created_at": "2025-05-01T09:00:00Z",
"updated_at": null,
"series_id": null,
"publishing_state": "processing",
"publish_at": "2025-05-01T10:00:00Z"
}
```
The video generation process might take some time. You can check its status via the **GET** `/videos/{id}` endpoint.
***
## Listing & Retrieving Videos
### List Videos
**Endpoint**: `GET /videos`
| Query Param | Default | Description |
| ----------- | ------- | -------------------------------------- |
| `page` | 0 | Results page number (zero-based index) |
| `limit` | 20 | Items per page |
{% tabs %}
{% tab title="TypeScript" %}
```typescript
const response = await client.getVideos({
page: 0,
limit: 10
})
console.log(`Found ${response.videos.length} videos`)
console.log(`Has more: ${response.hasMore}`)
for (const video of response.videos) {
console.log(`- ${video.title} (${video.id})`)
}
```
{% endtab %}
{% tab title="Python" %}
```python
response = client.videos.list(page=0, limit=10)
print(f"Found {len(response.videos)} videos")
print(f"Has more: {response.has_more}")
for video in response.videos:
print(f"- {video.title} ({video.id})")
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request GET \
--url "https://shortgenius.com/api/v1/videos?page=0&limit=10" \
--header "Authorization: Bearer YOUR_API_TOKEN"
```
{% endtab %}
{% endtabs %}
### Retrieve a Single Video
**Endpoint**: `GET /videos/{id}`
{% tabs %}
{% tab title="TypeScript" %}
```typescript
const video = await client.getVideo('98e19721-8b1e-45a8-abc2-555c7a6cd75d')
console.log(`Title: ${video.title}`)
console.log(`Status: ${video.publishingState}`)
console.log(`Created: ${video.createdAt}`)
```
{% endtab %}
{% tab title="Python" %}
```python
video = client.videos.retrieve("98e19721-8b1e-45a8-abc2-555c7a6cd75d")
print(f"Title: {video.title}")
print(f"Status: {video.publishing_state}")
print(f"Created: {video.created_at}")
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request GET \
--url "https://shortgenius.com/api/v1/videos/98e19721-8b1e-45a8-abc2-555c7a6cd75d" \
--header "Authorization: Bearer YOUR_API_TOKEN"
```
{% endtab %}
{% endtabs %}
***
## Generating Bulk Video Topics
Need multiple ideas for upcoming videos? ShortGenius can generate about 50ā100 unique topics in one go.
**Endpoint**: `POST /videos/topics`
{% tabs %}
{% tab title="TypeScript" %}
```typescript
const topics = await client.generateVideoTopics({
parentTopic: 'Water Conservation',
locale: 'en-US',
numberOfTopics: 50,
contentType: 'Custom'
})
console.log(`Generated ${topics.length} topics:`)
topics.slice(0, 5).forEach(topic => {
console.log(`- ${topic}`)
})
```
{% endtab %}
{% tab title="Python" %}
```python
topics = client.videos.generate_topics(
parent_topic="Water Conservation",
locale="en-US",
number_of_topics=50,
content_type="Custom"
)
print(f"Generated {len(topics)} topics:")
for topic in topics[:5]:
print(f"- {topic}")
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request POST \
--url "https://shortgenius.com/api/v1/videos/topics" \
--header "Authorization: Bearer YOUR_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"parent_topic": "Water Conservation",
"locale": "en-US",
"number_of_topics": 50,
"content_type": "Custom"
}'
```
{% endtab %}
{% endtabs %}
***
## Series (Batch or Ongoing Video Production)
If you want to create a continuous series of videos that follow a schedule, you can use the **/series** endpoints.
### Create a Video Series
**Endpoint**: `POST /series`
{% tabs %}
{% tab title="TypeScript" %}
```typescript
const series = await client.createSeries({
contentType: 'Custom',
locale: 'en-US',
connectionIds: [connections[0].id],
aspectRatio: '9:16',
topics: [{ topic: 'Tip 1: Reusable Water Bottles' }, { topic: 'Tip 2: Short Showers vs Baths' }],
schedule: {
timeZone: 'America/Denver',
times: [
{ dayOfWeek: 1, timeOfDay: 900 },
{ dayOfWeek: 3, timeOfDay: 1300 }
]
}
})
console.log(`Series created: ${series.id}`)
```
{% endtab %}
{% tab title="Python" %}
```python
series = client.series.create(
content_type="Custom",
locale="en-US",
connection_ids=[connections[0].id],
aspect_ratio="9:16",
topics=[
{"topic": "Tip 1: Reusable Water Bottles"},
{"topic": "Tip 2: Short Showers vs Baths"}
],
schedule={
"timeZone": "America/Denver",
"times": [
{"dayOfWeek": 1, "timeOfDay": 900},
{"dayOfWeek": 3, "timeOfDay": 1300}
]
}
)
print(f"Series created: {series.id}")
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request POST \
--url "https://shortgenius.com/api/v1/series" \
--header "Authorization: Bearer YOUR_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"content_type": "Custom",
"locale": "en-US",
"connection_ids": [""],
"aspect_ratio": "9:16",
"topics": [
{"topic": "Tip 1: Reusable Water Bottles"},
{"topic": "Tip 2: Short Showers vs Baths"}
],
"schedule": {
"timeZone": "America/Denver",
"times": [
{ "dayOfWeek": 1, "timeOfDay": 900 },
{ "dayOfWeek": 3, "timeOfDay": 1300 }
]
}
}'
```
{% endtab %}
{% endtabs %}
**Key Fields**:
* `topics` ā An array of topics for each episode
* `schedule` ā The day/time you want new episodes published
* `timeOfDay` uses 24-hour format but without a separator (e.g., `900` = 9:00, `1300` = 13:00)
**Sample Response**:
```json
{
"id": "c9b59ab6-2f1e-4c98-a833-e47e368c9615",
"created_at": "2025-05-10T09:00:00Z",
"next_posting_at": "2025-05-15T15:00:00Z",
"type": "Series",
"schedule": {
"time_zone": "America/Denver",
"times": [
{
"day_of_week": 1,
"time_of_day": 900
},
{
"day_of_week": 3,
"time_of_day": 1300
}
]
},
...
}
```
### List All Series
**Endpoint**: `GET /series`
{% tabs %}
{% tab title="TypeScript" %}
```typescript
const response = await client.getAllSeries({ page: 0, limit: 20 })
for (const series of response.series) {
console.log(`- ${series.id}: Next posting at ${series.nextPostingAt}`)
}
```
{% endtab %}
{% tab title="Python" %}
```python
response = client.series.list(page=0, limit=20)
for series in response.series:
print(f"- {series.id}: Next posting at {series.next_posting_at}")
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request GET \
--url "https://shortgenius.com/api/v1/series" \
--header "Authorization: Bearer YOUR_API_TOKEN"
```
{% endtab %}
{% endtabs %}
### Retrieve a Single Series
**Endpoint**: `GET /series/{id}`
Returns data about the series plus the individual **episodes** (videos) associated with it.
{% tabs %}
{% tab title="TypeScript" %}
```typescript
const series = await client.getSeries('c9b59ab6-2f1e-4c98-a833-e47e368c9615')
console.log(`Series type: ${series.type}`)
console.log(`Episodes: ${series.episodes?.length || 0}`)
```
{% endtab %}
{% tab title="Python" %}
```python
series = client.series.retrieve("c9b59ab6-2f1e-4c98-a833-e47e368c9615")
print(f"Series type: {series.type}")
print(f"Episodes: {len(series.episodes) if series.episodes else 0}")
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request GET \
--url "https://shortgenius.com/api/v1/series/c9b59ab6-2f1e-4c98-a833-e47e368c9615" \
--header "Authorization: Bearer YOUR_API_TOKEN"
```
{% endtab %}
{% endtabs %}
***
## Next Steps
You can now:
* Create video drafts from topics, scripts, or even news headlines.
* Finalize those drafts into fully rendered videos.
* Generate topics in bulk.
* Set up a video **series** with a publishing schedule.
Continue to the [Image Generation](/api/shortgenius-api/guides/video-generation) section to learn how to incorporate custom AI-generated images into your projects.
# Video Series
## Generating Bulk Video Topics
Need multiple ideas for upcoming videos? ShortGenius can generate about 50ā100 unique topics in one go.
**Endpoint**: `POST /videos/topics`
{% tabs %}
{% tab title="TypeScript" %}
```typescript
import { ShortGenius } from 'shortgenius'
const client = new ShortGenius({
bearerAuth: 'YOUR_API_TOKEN'
})
const topics = await client.generateVideoTopics({
parent_topic: 'Water Conservation',
locale: 'en-US',
number_of_topics: 50,
content_type: 'Custom'
})
console.log(`Generated ${topics.length} topics:`)
topics.slice(0, 5).forEach(topic => {
console.log(`- ${topic}`)
})
```
{% endtab %}
{% tab title="Python" %}
```python
from shortgenius import Shortgenius
client = Shortgenius(api_key="YOUR_API_TOKEN")
topics = client.videos.generate_topics(
parent_topic="Water Conservation",
locale="en-US",
number_of_topics=50,
content_type="Custom"
)
print(f"Generated {len(topics)} topics:")
for topic in topics[:5]:
print(f"- {topic}")
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request POST \
--url "https://shortgenius.com/api/v1/videos/topics" \
--header "Authorization: Bearer YOUR_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"parent_topic": "Water Conservation",
"locale": "en-US",
"number_of_topics": 50,
"content_type": "Custom"
}'
```
{% endtab %}
{% endtabs %}
**Sample Response**:
```json
[
"Why Saving Water Matters",
"Water Conservation Tips for Home",
"Rainwater Harvesting Basics",
...
]
```
***
## Series (Batch or Ongoing Video Production)
If you want to create a continuous series of videos that follow a schedule, you can use the **/series** endpoints.
### Create a Video Series
**Endpoint**: `POST /series`
{% tabs %}
{% tab title="TypeScript" %}
```typescript
const connections = await client.getConnections()
const series = await client.createSeries({
content_type: 'Custom',
locale: 'en-US',
connection_ids: [connections[0].id],
aspect_ratio: '9:16',
topics: [{ topic: 'Tip 1: Reusable Water Bottles' }, { topic: 'Tip 2: Short Showers vs Baths' }],
schedule: {
timeZone: 'America/Denver',
times: [
{ dayOfWeek: 1, timeOfDay: 900 },
{ dayOfWeek: 3, timeOfDay: 1300 }
]
}
})
console.log(`Series created: ${series.id}`)
console.log(`Next posting: ${series.next_posting_at}`)
```
{% endtab %}
{% tab title="Python" %}
```python
connections = client.connections.list()
series = client.series.create(
content_type="Custom",
locale="en-US",
connection_ids=[connections[0].id],
aspect_ratio="9:16",
topics=[
{"topic": "Tip 1: Reusable Water Bottles"},
{"topic": "Tip 2: Short Showers vs Baths"}
],
schedule={
"timeZone": "America/Denver",
"times": [
{"dayOfWeek": 1, "timeOfDay": 900},
{"dayOfWeek": 3, "timeOfDay": 1300}
]
}
)
print(f"Series created: {series.id}")
print(f"Next posting: {series.next_posting_at}")
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request POST \
--url "https://shortgenius.com/api/v1/series" \
--header "Authorization: Bearer YOUR_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"content_type": "Custom",
"locale": "en-US",
"connection_ids": [""],
"aspect_ratio": "9:16",
"topics": [
{"topic": "Tip 1: Reusable Water Bottles"},
{"topic": "Tip 2: Short Showers vs Baths"}
],
"schedule": {
"timeZone": "America/Denver",
"times": [
{ "dayOfWeek": 1, "timeOfDay": 900 },
{ "dayOfWeek": 3, "timeOfDay": 1300 }
]
}
}'
```
{% endtab %}
{% endtabs %}
**Key Fields**:
* `topics` ā An array of topics for each episode
* `schedule` ā The day/time you want new episodes published
* `timeOfDay` uses 24-hour format but without a separator (e.g., `900` = 9:00, `1300` = 13:00)
**Sample Response**:
```json
{
"id": "c9b59ab6-2f1e-4c98-a833-e47e368c9615",
"created_at": "2025-05-10T09:00:00Z",
"next_posting_at": "2025-05-15T15:00:00Z",
"type": "Series",
"schedule": {
"time_zone": "America/Denver",
"times": [
{
"day_of_week": 1,
"time_of_day": 900
},
{
"day_of_week": 3,
"time_of_day": 1300
}
]
},
...
}
```
### List All Series
**Endpoint**: `GET /series`
{% tabs %}
{% tab title="TypeScript" %}
```typescript
const response = await client.getAllSeries({
page: 0,
limit: 20
})
console.log(`Found ${response.series.length} series`)
console.log(`Has more: ${response.has_more}`)
for (const series of response.series) {
console.log(`- ${series.id}`)
console.log(` Type: ${series.type}`)
console.log(` Next posting: ${series.next_posting_at}`)
}
```
{% endtab %}
{% tab title="Python" %}
```python
response = client.series.list(page=0, limit=20)
print(f"Found {len(response.series)} series")
print(f"Has more: {response.has_more}")
for series in response.series:
print(f"- {series.id}")
print(f" Type: {series.type}")
print(f" Next posting: {series.next_posting_at}")
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request GET \
--url "https://shortgenius.com/api/v1/series" \
--header "Authorization: Bearer YOUR_API_TOKEN"
```
{% endtab %}
{% endtabs %}
### Retrieve a Single Series
**Endpoint**: `GET /series/{id}`
Returns data about the series plus the individual **episodes** (videos) associated with it.
{% tabs %}
{% tab title="TypeScript" %}
```typescript
const series = await client.getSeries('c9b59ab6-2f1e-4c98-a833-e47e368c9615')
console.log(`Series ID: ${series.id}`)
console.log(`Type: ${series.type}`)
console.log(`Created: ${series.created_at}`)
if (series.episodes) {
console.log(`\nEpisodes (${series.episodes.length}):`)
for (const episode of series.episodes) {
console.log(`- ${episode.title} (${episode.id})`)
console.log(` Status: ${episode.publishing_state}`)
}
}
```
{% endtab %}
{% tab title="Python" %}
```python
series = client.series.retrieve("c9b59ab6-2f1e-4c98-a833-e47e368c9615")
print(f"Series ID: {series.id}")
print(f"Type: {series.type}")
print(f"Created: {series.created_at}")
if series.episodes:
print(f"\nEpisodes ({len(series.episodes)}):")
for episode in series.episodes:
print(f"- {episode.title} ({episode.id})")
print(f" Status: {episode.publishing_state}")
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request GET \
--url "https://shortgenius.com/api/v1/series/c9b59ab6-2f1e-4c98-a833-e47e368c9615" \
--header "Authorization: Bearer YOUR_API_TOKEN"
```
{% endtab %}
{% endtabs %}
***
## Next Steps
You can now:
* Create video drafts from topics, scripts, or even news headlines.
* Finalize those drafts into fully rendered videos.
* Generate topics in bulk.
* Set up a video **series** with a publishing schedule.
Continue to the [Image Generation](/api/shortgenius-api/guides/video-generation) section to learn how to incorporate custom AI-generated images into your projects.
# Image Generation
ShortGenius includes a powerful AI image generation feature. By providing a text prompt and specifying an aspect ratio (and optionally an image style), you can quickly create unique visuals for your projects. This section covers creating, listing, retrieving, and customizing images.
## Creating Images
**Endpoint**: `POST /images`
### Basic Example
{% tabs %}
{% tab title="TypeScript" %}
```typescript
import { ShortGenius } from 'shortgenius'
const client = new ShortGenius({
bearerAuth: 'YOUR_API_TOKEN'
})
const image = await client.createImage({
prompt: 'A futuristic cityscape at sunset',
aspectRatio: '9:16',
waitForGeneration: true
})
console.log(`Image created: ${image.id}`)
console.log(`URL: ${image.url}`)
```
{% endtab %}
{% tab title="Python" %}
```python
from shortgenius import Shortgenius
client = Shortgenius(api_key="YOUR_API_TOKEN")
image = client.images.create(
prompt="A futuristic cityscape at sunset",
aspect_ratio="9:16",
wait_for_generation=True
)
print(f"Image created: {image.id}")
print(f"URL: {image.url}")
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request POST \
--url "https://shortgenius.com/api/v1/images" \
--header "Authorization: Bearer YOUR_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"prompt": "A futuristic cityscape at sunset",
"aspect_ratio": "9:16",
"wait_for_generation": true
}'
```
{% endtab %}
{% endtabs %}
**Key Fields**:
| Field | Type | Required | Description |
| --------------------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `prompt` | string | Yes | Text prompt for image creation. |
| `aspect_ratio` | string | Yes | One of `"9:16"`, `"16:9"`, or `"1:1"`. |
| `image_style_id` | string | No | An optional style preset. Retrieve available styles via **GET** `/images/styles`. |
| `scene_id` | string | No | If you want to attach this generated image to a particular video scene. |
| `wait_for_generation` | boolean | No | If **false**, the API returns immediately, and you must poll to see the final image. If **true**, it waits until the image is generated. |
#### Sample Response (Synchronous)
If `wait_for_generation` is **true**, and generation succeeds quickly, you might get a response like:
```json
{
"id": "b3e48cbd-7f89-4bd0-a9ad-f2f0afef63a3",
"url": "https://cdn.shortgenius.com/images/b3e48cbd.jpg",
"type": "GeneratedImage",
"state": "completed",
"created_at": "2025-05-01T12:00:00Z",
"updated_at": null,
"prompt": "A futuristic cityscape at sunset",
"is_nsfw": false,
"aspect_ratio": "9:16",
"image_style_id": null
}
```
If `wait_for_generation` is **false**, you might see `state: "pending"` or `state: "generating"`, and you'll need to poll the **GET** endpoint until the state becomes `"completed"`.
***
## Retrieving Images
You can list all images you've generated or retrieve a single one by its ID.
### List Images
**Endpoint**: `GET /images`
| Query Param | Default | Description |
| ----------- | ------- | -------------------------------- |
| `page` | 0 | Results page number (zero-based) |
| `limit` | 50 | Items per page, up to 200 |
{% tabs %}
{% tab title="TypeScript" %}
```typescript
const response = await client.getImages({
page: 0,
limit: 10
})
console.log(`Found ${response.images.length} images`)
for (const image of response.images) {
console.log(`- ${image.prompt} (${image.id})`)
console.log(` URL: ${image.url}`)
console.log(` State: ${image.state}`)
}
```
{% endtab %}
{% tab title="Python" %}
```python
response = client.images.list(page=0, limit=10)
print(f"Found {len(response.images)} images")
for image in response.images:
print(f"- {image.prompt} ({image.id})")
print(f" URL: {image.url}")
print(f" State: {image.state}")
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request GET \
--url "https://shortgenius.com/api/v1/images?page=0&limit=10" \
--header "Authorization: Bearer YOUR_API_TOKEN"
```
{% endtab %}
{% endtabs %}
### Retrieve a Single Image
**Endpoint**: `GET /images/{id}`
{% tabs %}
{% tab title="TypeScript" %}
```typescript
const image = await client.getImage('b3e48cbd-7f89-4bd0-a9ad-f2f0afef63a3')
console.log(`URL: ${image.url}`)
console.log(`State: ${image.state}`)
console.log(`Aspect Ratio: ${image.aspectRatio}`)
```
{% endtab %}
{% tab title="Python" %}
```python
image = client.images.retrieve("b3e48cbd-7f89-4bd0-a9ad-f2f0afef63a3")
print(f"Prompt: {image.prompt}")
print(f"URL: {image.url}")
print(f"State: {image.state}")
print(f"Aspect Ratio: {image.aspect_ratio}")
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request GET \
--url "https://shortgenius.com/api/v1/images/b3e48cbd-7f89-4bd0-a9ad-f2f0afef63a3" \
--header "Authorization: Bearer YOUR_API_TOKEN"
```
{% endtab %}
{% endtabs %}
***
## Image Styles
ShortGenius offers numerous **image styles** that apply artistic filters or aesthetic themes to your generated images. You can retrieve all available styles and use their IDs during image creation.
### List Image Styles
**Endpoint**: `GET /images/styles`
{% tabs %}
{% tab title="TypeScript" %}
```typescript
const styles = await client.getImageStyles()
console.log(`Found ${styles.length} image styles:`)
for (const style of styles) {
console.log(`- ${style.name} (${style.id})`)
console.log(` Prompt: ${style.prompt}`)
console.log(` Examples: ${style.examples.join(', ')}`)
}
```
{% endtab %}
{% tab title="Python" %}
```python
styles = client.images.list_styles()
print(f"Found {len(styles)} image styles:")
for style in styles:
print(f"- {style.name} ({style.id})")
print(f" Prompt: {style.prompt}")
print(f" Examples: {', '.join(style.examples)}")
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request GET \
--url "https://shortgenius.com/api/v1/images/styles" \
--header "Authorization: Bearer YOUR_API_TOKEN"
```
{% endtab %}
{% endtabs %}
You can use these IDs in the `image_style_id` field when creating images:
{% tabs %}
{% tab title="TypeScript" %}
```typescript
// Get available styles
const styles = await client.getImageStyles()
const cyberpunkStyle = styles.find(s => s.name === 'Cyberpunk')
// Create image with style
const image = await client.createImage({
prompt: 'A robotic cat with glowing eyes',
aspectRatio: '9:16',
imageStyleId: cyberpunkStyle?.id,
waitForGeneration: true
})
```
{% endtab %}
{% tab title="Python" %}
```python
# Get available styles
styles = client.images.list_styles()
cyberpunk_style = next((s for s in styles if s.name == "Cyberpunk"), None)
# Create image with style
image = client.images.create(
prompt="A robotic cat with glowing eyes",
aspect_ratio="9:16",
image_style_id=cyberpunk_style.id if cyberpunk_style else None,
wait_for_generation=True
)
```
{% endtab %}
{% tab title="cURL" %}
```bash
--data '{
"prompt": "A robotic cat with glowing eyes",
"aspect_ratio": "9:16",
"image_style_id": "01b28da2-96fa-42f9-9efc-3d17ff042882"
}'
```
{% endtab %}
{% endtabs %}
***
## Attaching Images to Videos
While drafting or creating videos, you can include AI-generated images in the video scenes, by either:
1. Generating the image first, then embedding the `id` or `url` into a scene.
2. Specifying a `scene_id` when calling `POST /images`, so the platform automatically associates it.
Here's a simplified example of attaching an existing image to a video scene:
{% tabs %}
{% tab title="TypeScript" %}
```typescript
// Generate image first
const image = await client.createImage({
prompt: 'A futuristic city skyline',
aspectRatio: '9:16',
waitForGeneration: true
})
// Use image in video creation
const video = await client.createVideo({
// ... other fields ...
scenes: [
{
title: 'Intro',
caption: 'Check out this futuristic city!',
first_image_id: image.id
}
]
})
```
{% endtab %}
{% tab title="Python" %}
```python
# Generate image first
image = client.images.create(
prompt="A futuristic city skyline",
aspect_ratio="9:16",
wait_for_generation=True
)
# Use image in video creation
video = client.videos.create(
# ... other fields ...
scenes=[
{
"title": "Intro",
"caption": "Check out this futuristic city!",
"first_image_id": image.id
}
]
)
```
{% endtab %}
{% tab title="JSON Structure" %}
```json
{
"scenes": [
{
"title": "Intro",
"caption": "Check out this futuristic city!",
"first_image_description": null,
"second_image_description": null,
"first_image_id": "b3e48cbd-7f89-4bd0-a9ad-f2f0afef63a3"
}
]
}
```
{% endtab %}
{% endtabs %}
***
## Next Steps
Now that you know how to generate and retrieve images, let's move on to [Audio Generation (Text-to-Speech)](/api/shortgenius-api/guides/image-generation). You can create voiceovers or add TTS audio to your automated videos for a more immersive experience.
# Audio Generation
ShortGenius can turn any piece of text into a narrated audio file using its text-to-speech (TTS) engine. Choose from various **voices** and locales to match your brand or project needs. This section covers creating speech, listing existing audio, and retrieving detailed audio info.
***
## Creating Speech
**Endpoint**: `POST /audio/speech`
Use this endpoint to generate a new audio file from text. You can optionally let the request return immediately or wait until the audio is fully generated.
{% tabs %}
{% tab title="TypeScript" %}
```typescript
import { ShortGenius } from 'shortgenius'
const client = new ShortGenius({
bearerAuth: 'YOUR_API_TOKEN'
})
// Get a voice first
const voices = await client.getVoices({ locale: 'en-US' })
const voice = voices[0]
// Create speech
const audio = await client.createSpeech({
text: 'Hello from ShortGenius!',
locale: 'en-US',
voiceId: voice.id,
waitForGeneration: true
})
console.log(`Audio created: ${audio.id}`)
console.log(`URL: ${audio.url}`)
console.log(`Duration: ${audio.duration}s`)
```
{% endtab %}
{% tab title="Python" %}
```python
from shortgenius import Shortgenius
client = Shortgenius(api_key="YOUR_API_TOKEN")
# Get a voice first
voices = client.audio.voices.list_voices(locale="en-US")
voice = voices[0]
# Create speech
audio = client.audio.create_speech(
text="Hello from ShortGenius!",
locale="en-US",
voice_id=voice.id,
wait_for_generation=True
)
print(f"Audio created: {audio.id}")
print(f"URL: {audio.url}")
print(f"Duration: {audio.duration}s")
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request POST \
--url "https://shortgenius.com/api/v1/audio/speech" \
--header "Authorization: Bearer YOUR_API_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"text": "Hello from ShortGenius!",
"locale": "en-US",
"voice_id": "9BWtsMINqrJLrRacOk9x",
"wait_for_generation": true
}'
```
{% endtab %}
{% endtabs %}
### Request Fields
| Field | Type | Required | Description |
| --------------------- | ------- | -------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `text` | string | Yes | The text to be converted to speech. |
| `voice_id` | string | Yes | ID of the chosen voice. See [List Voices](#list-voices) to retrieve possible `voice_id`. |
| `locale` | string | No | Defaults to `"auto"`. Use a two-letter language code + region code if you want to specify a locale (e.g., `en-US`, `de-DE`). |
| `wait_for_generation` | boolean | No | If **false**, the response immediately returns a pending record. If **true**, it waits until the audio is ready (default: false). |
### Sample Response (Synchronous)
If `wait_for_generation` is **true** and generation completes quickly, you'll receive:
```json
{
"id": "3804fef4-5329-42b8-8a5b-a12eb5c3dc2c",
"created_at": "2025-05-05T14:00:00Z",
"updated_at": null,
"url": "https://cdn.shortgenius.com/audio/3804fef4.mp3",
"user_id": "8f157306-139a-4f38-b783-e13e326ecaaa",
"transcript": {
"words": [
{
"text": "Hello",
"start": 0.4,
"end": 0.7,
"confidence": 0.99
},
{
"text": "from",
"start": 0.75,
"end": 1.0,
"confidence": 0.98
},
...
]
},
"state": "completed",
"text": "Hello from ShortGenius!",
"locale": "en-US",
"voice": {
"id": "769d93d4-3c7f-47c0-9a9c-5db259e67b95",
"name": "Samantha",
"description": null,
"avatar_url": null,
"flag_url": null,
"tags": null,
"preview_url": null,
"locale": "en-US",
"source": "ElevenLabs"
},
"duration": 1.2,
"lufs": -14.3
}
```
If `wait_for_generation` is **false**, you may see `"state": "pending"` or `"generating"`, and you need to poll the [Get Audio](#retrieve-a-single-audio) endpoint until it's `"completed"`.
***
## Listing & Retrieving Audio
### List Audio
**Endpoint**: `GET /audio`
| Query Param | Default | Description |
| ----------- | ------- | -------------------------------- |
| `page` | 0 | Results page number (zero-based) |
| `limit` | 50 | Items per page, up to 200 |
{% tabs %}
{% tab title="cURL" %}
```bash
curl --request GET \
--url "https://shortgenius.com/api/v1/audio?page=0&limit=10" \
--header "Authorization: Bearer YOUR_API_TOKEN"
```
{% endtab %}
{% tab title="TypeScript" %}
```typescript
const response = await client.getAllAudio({
page: 0,
limit: 10
})
console.log(`Found ${response.audio.length} audio files`)
console.log(`Has more: ${response.hasMore}`)
for (const audio of response.audio) {
console.log(`- ${audio.text} (${audio.id})`)
console.log(` Voice: ${audio.voice.name}`)
console.log(` State: ${audio.state}`)
}
```
{% endtab %}
{% tab title="Python" %}
```python
response = client.audio.list_audio(page=0, limit=10)
print(f"Found {len(response.audio)} audio files")
print(f"Has more: {response.has_more}")
for audio in response.audio:
print(f"- {audio.text} ({audio.id})")
print(f" Voice: {audio.voice.name}")
print(f" State: {audio.state}")
```
{% endtab %}
{% endtabs %}
### Retrieve a Single Audio
**Endpoint**: `GET /audio/{id}`
{% tabs %}
{% tab title="cURL" %}
```bash
curl --request GET \
--url "https://shortgenius.com/api/v1/audio/3804fef4-5329-42b8-8a5b-a12eb5c3dc2c" \
--header "Authorization: Bearer YOUR_API_TOKEN"
```
{% endtab %}
{% tab title="TypeScript" %}
```typescript
const audio = await client.getAudio('3804fef4-5329-42b8-8a5b-a12eb5c3dc2c')
console.log(`Text: ${audio.text}`)
console.log(`Voice: ${audio.voice.name}`)
console.log(`State: ${audio.state}`)
console.log(`Duration: ${audio.duration}s`)
console.log(`URL: ${audio.url}`)
// Access transcript if available
if (audio.transcript) {
console.log('Transcript words:', audio.transcript.words.length)
}
```
{% endtab %}
{% tab title="Python" %}
```python
audio = client.audio.retrieve_audio("3804fef4-5329-42b8-8a5b-a12eb5c3dc2c")
print(f"Text: {audio.text}")
print(f"Voice: {audio.voice.name}")
print(f"State: {audio.state}")
print(f"Duration: {audio.duration}s")
print(f"URL: {audio.url}")
# Access transcript if available
if audio.transcript:
print(f"Transcript words: {len(audio.transcript.words)}")
```
{% endtab %}
{% endtabs %}
***
## Voices
ShortGenius offers a wide selection of voices with distinct accents, languages, and tonalities. You can filter them by locale or retrieve details about a specific voice.
### List Voices
**Endpoint**: `GET /audio/voices`
| Query Param | Default | Description |
| ----------- | ------- | ------------------------------------------------------ |
| `locale` | `auto` | Language/region code to filter voices (e.g., `en-US`). |
| `page` | 0 | Page number. |
| `limit` | 20 | Items per page, can go up to 10,000,000. |
{% tabs %}
{% tab title="cURL" %}
```bash
curl --request GET \
--url "https://shortgenius.com/api/v1/audio/voices?locale=en-US&page=0&limit=5" \
--header "Authorization: Bearer YOUR_API_TOKEN"
```
{% endtab %}
{% tab title="TypeScript" %}
```typescript
const voices = await client.getVoices({
locale: 'en-US',
page: 0,
limit: 5
})
console.log(`Found ${voices.length} voices:`)
for (const voice of voices) {
console.log(`- ${voice.name} (${voice.id})`)
console.log(` Locale: ${voice.locale}`)
console.log(` Source: ${voice.source}`)
if (voice.tags) {
console.log(` Gender: ${voice.tags.gender}`)
console.log(` Accent: ${voice.tags.accent}`)
}
if (voice.previewUrl) {
console.log(` Preview: ${voice.previewUrl}`)
}
}
```
{% endtab %}
{% tab title="Python" %}
```python
voices = client.audio.voices.list_voices(
locale="en-US",
page=0,
limit=5
)
print(f"Found {len(voices)} voices:")
for voice in voices:
print(f"- {voice.name} ({voice.id})")
print(f" Locale: {voice.locale or 'Not specified'}")
print(f" Source: {voice.source}")
if voice.tags:
print(f" Gender: {voice.tags.gender}")
print(f" Accent: {voice.tags.accent}")
if voice.preview_url:
print(f" Preview: {voice.preview_url}")
```
{% endtab %}
{% endtabs %}
### Retrieve a Single Voice
**Endpoint**: `GET /audio/voices/{id}`
{% tabs %}
{% tab title="cURL" %}
```bash
curl --request GET \
--url "https://shortgenius.com/api/v1/audio/voices/769d93d4-3c7f-47c0-9a9c-5db259e67b95" \
--header "Authorization: Bearer YOUR_API_TOKEN"
```
{% endtab %}
{% tab title="TypeScript" %}
```typescript
const voice = await client.getVoice('769d93d4-3c7f-47c0-9a9c-5db259e67b95')
console.log(`Name: ${voice.name}`)
console.log(`Locale: ${voice.locale}`)
console.log(`Source: ${voice.source}`)
if (voice.tags) {
console.log('Tags:', voice.tags)
}
if (voice.previewUrl) {
console.log(`Preview URL: ${voice.previewUrl}`)
}
```
{% endtab %}
{% tab title="Python" %}
```python
voice = client.audio.voices.retrieve_voice("769d93d4-3c7f-47c0-9a9c-5db259e67b95")
print(f"Name: {voice.name}")
print(f"Locale: {voice.locale or 'Not specified'}")
print(f"Source: {voice.source}")
if voice.tags:
print(f"Tags: {voice.tags}")
if voice.preview_url:
print(f"Preview URL: {voice.preview_url}")
```
{% endtab %}
{% endtabs %}
***
## Complete Example
Here's a complete example that demonstrates voice selection and audio generation:
{% tabs %}
{% tab title="TypeScript" %}
```typescript
import { ShortGenius } from 'shortgenius'
const client = new ShortGenius({
bearerAuth: 'YOUR_API_TOKEN'
})
async function generateNarration() {
// 1. Find a suitable voice
const voices = await client.getVoices({
locale: 'en-US',
limit: 100
})
// Filter for female conversational voices
const femaleVoices = voices.filter(v => v.tags?.gender === 'Female' && v.tags?.tone === 'Conversational')
if (femaleVoices.length === 0) {
console.error('No suitable voices found')
return
}
const selectedVoice = femaleVoices[0]
console.log(`Selected voice: ${selectedVoice.name}`)
// 2. Generate speech
const audio = await client.createSpeech({
text: "Welcome to ShortGenius! Let's create amazing content together.",
voiceId: selectedVoice.id,
locale: 'en-US',
waitForGeneration: true
})
console.log(`Audio generated successfully!`)
console.log(`URL: ${audio.url}`)
console.log(`Duration: ${audio.duration}s`)
return audio
}
generateNarration()
```
{% endtab %}
{% tab title="Python" %}
```python
from shortgenius import Shortgenius
client = Shortgenius(api_key="YOUR_API_TOKEN")
def generate_narration():
# 1. Find a suitable voice
voices = client.audio.voices.list_voices(locale="en-US", limit=100)
# Filter for female conversational voices
female_voices = [
v for v in voices
if v.tags and
v.tags.gender == "Female" and
hasattr(v.tags, 'tone') and v.tags.tone == "Conversational"
]
if not female_voices:
print("No suitable voices found")
return
selected_voice = female_voices[0]
print(f"Selected voice: {selected_voice.name}")
# 2. Generate speech
audio = client.audio.create_speech(
text="Welcome to ShortGenius! Let's create amazing content together.",
voice_id=selected_voice.id,
locale="en-US",
wait_for_generation=True
)
print("Audio generated successfully!")
print(f"URL: {audio.url}")
print(f"Duration: {audio.duration}s")
return audio
generate_narration()
```
{% endtab %}
{% endtabs %}
***
## Best Practices & Tips
* **Preview Voices**: Use the `preview_url` from the voices list to quickly audition how a voice sounds.
* **Check Credits**: Generating long or high-quality TTS may consume more credits, so keep an eye on [credits](https://github.com/ShortGenius/shorts/blob/main/authentication-and-essentials.md#rate-limits--credits).
* **Combine with Video**: Add TTS audio to your [video drafts](https://github.com/ShortGenius/shorts/blob/main/video-generation.md) for a more engaging, fully AI-generated experience.
***
## Next Steps
Now you know how to:
1. Generate audio from text using TTS.
2. Retrieve or list audio files.
3. Explore a variety of voices.
Continue to the [Music](/api/shortgenius-api/guides/audio-generation) section to see how you can add music soundtracks, or head to the [Connections & Publishing](/api/shortgenius-api/guides/audio-generation) chapter to learn how to publish your creations automatically.
# Music
ShortGenius also provides an AI-curated music catalog to serve as background tracks for your videos. You can explore various genres and pick specific tracks to add life to your video content.
## List Music Genres
**Endpoint**: `GET /music/genres`
Retrieve the full list of available music genres. Each genre may include recommended locales where that genre is particularly popular.
{% tabs %}
{% tab title="TypeScript" %}
```typescript
import { ShortGenius } from 'shortgenius'
const client = new ShortGenius({
bearerAuth: 'YOUR_API_TOKEN'
})
const genres = await client.getMusicGenres()
console.log(`Found ${genres.length} music genres:`)
for (const genre of genres) {
console.log(`- ${genre.name}`)
if (genre.recommended_for_locales && genre.recommended_for_locales.length > 0) {
console.log(` Recommended for: ${genre.recommended_for_locales.join(', ')}`)
}
}
```
{% endtab %}
{% tab title="Python" %}
```python
from shortgenius import Shortgenius
client = Shortgenius(api_key="YOUR_API_TOKEN")
genres = client.music.genres.list()
print(f"Found {len(genres)} music genres:")
for genre in genres:
print(f"- {genre.name}")
if genre.recommended_for_locales:
print(f" Recommended for: {', '.join(genre.recommended_for_locales)}")
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request GET \
--url "https://shortgenius.com/api/v1/music/genres" \
--header "Authorization: Bearer YOUR_API_TOKEN"
```
{% endtab %}
{% endtabs %}
**Sample Response**:
```json
[
{
"name": "Classical",
"recommended_for_locales": [
"de-DE",
"fr-FR",
"en-US"
]
},
{
"name": "Jazz",
"recommended_for_locales": [
"en-US",
"fr-FR"
]
},
...
]
```
### Response Fields
| Field | Description |
| ------------------------- | --------------------------------------------------------- |
| `name` | The name of the genre (e.g., `"Classical"`). |
| `recommended_for_locales` | Array of locales where the genre is particularly popular. |
***
## List Music in a Genre
**Endpoint**: `GET /music/genres/{id}`
Use the **genre's name** or **unique ID** returned by `GET /music/genres` to list specific tracks.
{% tabs %}
{% tab title="TypeScript" %}
```typescript
// First get genres to find the ID
const genres = await client.getMusicGenres()
const classicalGenre = genres.find(g => g.name === 'Classical')
if (classicalGenre) {
const tracks = await client.getMusic(classicalGenre.id)
console.log(`Found ${tracks.length} tracks in ${classicalGenre.name}:`)
for (const track of tracks) {
console.log(`- ${track.name} (${track.id})`)
if (track.preview_url) {
console.log(` Preview: ${track.preview_url}`)
}
}
}
```
{% endtab %}
{% tab title="Python" %}
```python
# First get genres to find the ID
genres = client.music.genres.list()
classical_genre = next((g for g in genres if g.name == "Classical"), None)
if classical_genre:
tracks = client.music.tracks.list(genre_id=classical_genre.id)
print(f"Found {len(tracks)} tracks in {classical_genre.name}:")
for track in tracks:
print(f"- {track.name} ({track.id})")
if track.preview_url:
print(f" Preview: {track.preview_url}")
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request GET \
--url "https://shortgenius.com/api/v1/music/genres/Classical" \
--header "Authorization: Bearer YOUR_API_TOKEN"
```
{% endtab %}
{% endtabs %}
**Sample Response**:
```json
[
{
"id": "73f3cd22-bd13-4ec1-a675-82de290c598f",
"name": "Moonlight Sonata (Excerpt)",
"preview_url": "https://cdn.shortgenius.com/music/73f3cd22-preview.mp3"
},
{
"id": "ee13c403-6503-49c4-9ff8-a9a45eb558bb",
"name": "Fur Elise (Excerpt)",
"preview_url": "https://cdn.shortgenius.com/music/ee13c403-preview.mp3"
},
...
]
```
### Response Fields
| Field | Description |
| ------------- | ----------------------------------------------------------- |
| `id` | Unique ID of the track (for use in `/videos` or `/series`). |
| `name` | Track title (may be partial or excerpt). |
| `preview_url` | Direct link to a short preview audio clip of the track. |
***
## Using Music in Videos
After identifying a suitable track's `id`, simply include it in your request to **create** or **update** a video:
{% tabs %}
{% tab title="TypeScript" %}
```typescript
// Get a soundtrack
const genres = await client.getMusicGenres()
const tracks = await client.getMusic(genres[0].id)
// Use in video creation
const video = await client.createVideo({
// ... other video fields ...
soundtrack_id: tracks[0].id,
soundtrack_volume: 80,
soundtrack_playback_rate: 120
})
console.log(`Video created with soundtrack: ${tracks[0].name}`)
```
{% endtab %}
{% tab title="Python" %}
```python
# Get a soundtrack
genres = client.music.genres.list()
tracks = client.music.tracks.list(genre_id=genres[0].id)
# Use in video creation
video = client.videos.create(
# ... other video fields ...
soundtrack_id=tracks[0].id,
soundtrack_volume=80,
soundtrack_playback_rate=120
)
print(f"Video created with soundtrack: {tracks[0].name}")
```
{% endtab %}
{% tab title="JSON" %}
```json
{
"soundtrack_id": "73f3cd22-bd13-4ec1-a675-82de290c598f",
"soundtrack_volume": 80,
"soundtrack_playback_rate": 120
}
```
{% endtab %}
{% endtabs %}
ShortGenius will overlay this music behind your AI-generated voice and scenes, producing a fully scored video.
***
## Next Steps
Now that you can add background music:
1. Check out [Connections & Publishing](/api/shortgenius-api/guides/music) to learn how to publish your videos.
2. Monitor your [Usage & Credits](/api/shortgenius-api/guides/music) so you always have enough resources to generate new music-backed projects.
# Publishing
ShortGenius lets you publish your videos automatically to various platforms (TikTok, YouTube, X, etc.). This section covers how to manage these connections and how to utilize them in your video creation workflow.
***
## Listing Publishing Destinations
**Endpoint**: `GET /connections`
This endpoint returns all the publishing destinations (a.k.a. "connections") you've set up in your ShortGenius account. Examples include TikTok, YouTube, X, and Email.
{% tabs %}
{% tab title="TypeScript" %}
```typescript
import { ShortGenius } from 'shortgenius'
const client = new ShortGenius({
bearerAuth: 'YOUR_API_TOKEN'
})
const connections = await client.getConnections()
console.log(`Found ${connections.length} connections:`)
for (const connection of connections) {
console.log(`- ${connection.name} (${connection.type}): ${connection.id}`)
}
```
{% endtab %}
{% tab title="Python" %}
```python
from shortgenius import Shortgenius
client = Shortgenius(api_key="YOUR_API_TOKEN")
connections = client.connections.list()
print(f"Found {len(connections)} connections:")
for connection in connections:
print(f"- {connection.name} ({connection.type}): {connection.id}")
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request GET \
--url "https://shortgenius.com/api/v1/connections" \
--header "Authorization: Bearer YOUR_API_TOKEN"
```
{% endtab %}
{% endtabs %}
**Sample Response**:
```json
[
{
"id": "95c87129-3e78-49ee-8305-d7bd5201263a",
"type": "TikTok",
"name": "My TikTok Account"
},
{
"id": "00d10d95-b58c-4a60-9cae-578490ab5201",
"type": "YouTube",
"name": "My YouTube Channel"
},
{
"id": "9830b2d9-76f7-4471-b5f6-a33041555c75",
"type": "X",
"name": "My Twitter/X Profile"
}
]
```
### Response Fields
| Field | Description |
| ------ | ---------------------------------------------------------------------------------------------- |
| `id` | Unique ID for this connection. You'll pass this to **/videos** or **/series** when publishing. |
| `type` | The platform type (e.g., `"TikTok"`, `"YouTube"`, `"X"`, `"Email"`). |
| `name` | A user-friendly name for your reference. |
***
## Using Connections in Video Creation
When creating or scheduling videos and series, you can specify which connection(s) to publish to.
For example, in **`POST /videos`**:
{% tabs %}
{% tab title="TypeScript" %}
```typescript
// Get your connections first
const connections = await client.getConnections()
const tiktokConnection = connections.find(c => c.type === 'TikTok')
// Create a video with publishing
const video = await client.createVideo({
connectionIds: [tiktokConnection.id],
title: 'Fun AI Video',
caption: 'Check out this AI-created content!',
contentType: 'Custom',
locale: 'en-US',
scenes: draft.scenes, // from your draft
voiceId: voice.id,
aspectRatio: '9:16' // 9:16 for TikTok
})
console.log(`Video will be published to ${tiktokConnection.name}`)
```
{% endtab %}
{% tab title="Python" %}
```python
# Get your connections first
connections = client.connections.list()
tiktok_connection = next((c for c in connections if c.type == "TikTok"), None)
# Create a video with publishing
video = client.videos.create(
connection_ids=[tiktok_connection.id],
title="Fun AI Video",
caption="Check out this AI-created content!",
content_type="Custom",
locale="en-US",
scenes=draft.scenes, # from your draft
voice_id=voice.id,
aspect_ratio="916" # 9:16 for TikTok
)
print(f"Video will be published to {tiktok_connection.name}")
```
{% endtab %}
{% tab title="JSON Structure" %}
```json
{
"connection_ids": [
"95c87129-3e78-49ee-8305-d7bd5201263a"
],
"title": "Fun AI Video",
"caption": "Check out this AI-created content!",
...
}
```
{% endtab %}
{% endtabs %}
ShortGenius will automatically publish the generated video to the specified platform once it finishes rendering (and according to any `publish_at` scheduling you set).
### Scheduling Videos
If you use the `publish_at` field in your `POST /videos` body, ShortGenius will **delay** the publish time until your desired date/time (in ISO 8601 format). For example:
{% tabs %}
{% tab title="TypeScript" %}
```typescript
const scheduledDate = new Date()
scheduledDate.setDate(scheduledDate.getDate() + 7) // 1 week from now
const video = await client.createVideo({
// ... other fields ...
publishAt: scheduledDate.toISOString()
})
console.log(`Video scheduled for ${scheduledDate.toLocaleString()}`)
```
{% endtab %}
{% tab title="Python" %}
```python
from datetime import datetime, timedelta
scheduled_date = datetime.now() + timedelta(days=7) # 1 week from now
video = client.videos.create(
# ... other fields ...
publish_at=scheduled_date.isoformat() + "Z"
)
print(f"Video scheduled for {scheduled_date}")
```
{% endtab %}
{% tab title="JSON" %}
```json
"publish_at": "2025-06-01T10:00:00Z"
```
{% endtab %}
{% endtabs %}
When that time arrives, ShortGenius begins publishing to your designated connections (e.g., TikTok, YouTube, etc.).
***
## Using Connections in Series
Similarly, for **`POST /series`**, include an array of `connection_ids` to apply an automated schedule across multiple episodes:
{% tabs %}
{% tab title="TypeScript" %}
```typescript
const connections = await client.getConnections()
const youtubeConnection = connections.find(c => c.type === 'YouTube')
const xConnection = connections.find(c => c.type === 'X')
const series = await client.createSeries({
connection_ids: [youtubeConnection.id, xConnection.id],
aspect_ratio: '9:16',
locale: 'en-US',
content_type: 'Custom',
topics: [{ topic: 'AI Basics: What is Machine Learning?' }, { topic: 'AI Basics: Neural Networks Explained' }],
schedule: {
timeZone: 'America/Denver',
times: [
{ dayOfWeek: 2, timeOfDay: 900 } // Tuesday at 9:00 AM
]
}
})
console.log(`Series will publish to ${[youtubeConnection.name, xConnection.name].join(' and ')}`)
```
{% endtab %}
{% tab title="Python" %}
```python
connections = client.connections.list()
youtube_connection = next((c for c in connections if c.type == "YouTube"), None)
x_connection = next((c for c in connections if c.type == "X"), None)
series = client.series.create(
connection_ids=[youtube_connection.id, x_connection.id],
aspect_ratio="9:16",
locale="en-US",
content_type="Custom",
topics=[
{"topic": "AI Basics: What is Machine Learning?"},
{"topic": "AI Basics: Neural Networks Explained"}
],
schedule={
"timeZone": "America/Denver",
"times": [
{"dayOfWeek": 2, "timeOfDay": 900} # Tuesday at 9:00 AM
]
}
)
print(f"Series will publish to {youtube_connection.name} and {x_connection.name}")
```
{% endtab %}
{% tab title="cURL" %}
```json
{
"connection_ids": [
"00d10d95-b58c-4a60-9cae-578490ab5201",
"9830b2d9-76f7-4471-b5f6-a33041555c75"
],
"aspect_ratio": "9:16",
"locale": "en-US",
"schedule": {
"timeZone": "America/Denver",
"times": [
{ "dayOfWeek": 2, "timeOfDay": 900 }
]
},
...
}
```
{% endtab %}
{% endtabs %}
Each video in that series will automatically publish to the selected platforms at the scheduled times.
***
## Publishing State
ShortGenius tracks the **publishing\_state** of each video:
* **`pending`** ā Video is waiting to be processed or published.
* **`processing`** ā Video is being rendered or is about to be uploaded.
* **`completed`** ā Successfully published.
* **`skipped`** ā Publishing skipped for some reason (e.g., missing credentials).
* **`error`** ā An error occurred during publishing.
You can view this state in the response from:
* **`GET /videos`**
* **`GET /videos/{id}`**
* **`GET /series/{id}`** (for each episode)
***
## Troubleshooting Publishing
If publishing fails:
1. Check your connection credentials on the ShortGenius **dashboard**.
2. Ensure your publishing time (`publish_at`) is not in the past.
3. Review the error in the video's `publishing_state`. If you see `"error"`, there may be a message in the response body (such as missing permissions).
***
## Next Steps
Now that you can publish and schedule your AI-generated videos, you might want to keep an eye on your usage and credits. Head over to the [Usage & Credits](/api/shortgenius-api/guides/publishing) section to learn how to manage resources effectively.
# Usage & Credits
ShortGenius operates on a **credit-based system** to manage resource-intensive AI processes (video creation, image generation, text-to-speech, etc.). This section explains how to retrieve your current credit balances and interpret usage details.
***
## Get Usage (Credits)
**Endpoint**: `GET /credits`
Use this endpoint to see your current balance of credits.
{% tabs %}
{% tab title="TypeScript" %}
```typescript
import { ShortGenius } from 'shortgenius'
const client = new ShortGenius({
bearerAuth: 'YOUR_API_TOKEN'
})
const usage = await client.getUsage()
console.log('Credit Balance:')
console.log(` General credits: ${usage.balance.credits}`)
console.log(` High quality video credits: ${usage.balance.highQualityVideoCredits || 0}`)
```
{% endtab %}
{% tab title="Python" %}
```python
from shortgenius import Shortgenius
client = Shortgenius(api_key="YOUR_API_TOKEN")
usage = client.usage.get()
print("Credit Balance:")
print(f" General credits: {usage.balance.credits}")
print(f" High quality video credits: {usage.balance.high_quality_video_credits or 0}")
```
{% endtab %}
{% tab title="cURL" %}
```bash
curl --request GET \
--url "https://shortgenius.com/api/v1/credits" \
--header "Authorization: Bearer YOUR_API_TOKEN"
```
{% endtab %}
{% endtabs %}
**Sample Response**:
```json
{
"balance": {
"credits": 217,
"high_quality_video_credits": 1
}
}
```
### Understanding the Credit Types
| Field | Description |
| ---------------------------- | --------------------------------------------------------------------- |
| `credits` | General-purpose credits used for standard video creation, audio, etc. |
| `high_quality_video_credits` | Specialized credits for higher-resolution or premium video rendering. |
***
## When Are Credits Deducted?
Credits are deducted whenever you:
1. **Generate a new video** (drafting may or may not consume minimal credits, but final creation deducts the majority).
2. **Generate images** (each request uses at least one image credit).
3. **Create text-to-speech audio** (some usage policies may apply, depending on length or voice type).
The exact cost per request may vary based on your plan and the complexity of the task. Check your [ShortGenius dashboard](https://shortgenius.com) for detailed pricing.
***
## Best Practices for Credit Management
1. **Check Your Balance Regularly**\
Use `GET /credits` before launching large-scale generation tasks.
2. **Batch Your Requests**\
Instead of multiple small calls, sometimes it's more cost-effective to batch generation (e.g., series or bulk topics).
3. **Optimize Drafts**\
**Draft** your video scripts first, then carefully finalize them to avoid accidental re-renders that use up credits.
4. **Monitor Renewal Cycles**\
If you're on a subscription plan with monthly credit resets, align your bigger projects when credits refresh.
***
## Error Handling with Insufficient Credits
If you attempt an operation but don't have enough credits, you'll typically see:
```json
{
"message": "Insufficient credits"
}
```
or a **400/402** status code, depending on how the system classifies the shortfall.
{% tabs %}
{% tab title="TypeScript" %}
```typescript
import { APIError } from 'shortgenius'
// Check credits before expensive operations
const usage = await client.getUsage()
if (usage.balance.credits < 10) {
console.warn('Low on credits!')
}
// Handle insufficient credit errors
const video = await client
.createVideo({
// ... video parameters ...
})
.catch(error => {
if (error instanceof APIError && error.status === 402) {
console.error('Insufficient credits to create video')
}
throw error
})
```
{% endtab %}
{% tab title="Python" %}
```python
from shortgenius.types import APIError
# Check credits before expensive operations
usage = client.usage.get()
if usage.balance.credits < 10:
print("Warning: Low on credits!")
# Handle insufficient credit errors
try:
video = client.videos.create(
# ... video parameters ...
)
except APIError as e:
if e.status_code == 402:
print("Insufficient credits to create video")
raise
```
{% endtab %}
{% endtabs %}
***
## Next Steps
You've now covered:
1. **How to retrieve your credit balance.**
2. **When credits are deducted.**
3. **Tips for efficient credit usage.**
For additional tips and real-world workflows, check out the [Guides & Tutorials](/api/shortgenius-api/guides/usage-credits) section. Or, if you need a deep dive into every endpoint's request/response, visit the [Reference](/api/shortgenius-api/guides/usage-credits) section.
# Videos