Python Client
Use indream-client with sync and async clients.
Install
pip install indream-clientSync Client
from indream import IndreamClient
client = IndreamClient(
api_key="<YOUR_API_KEY>",
base_url="https://api.indream.ai",
timeout=60,
max_retries=2,
)Search Illustrations
Search by keyword when you need a supported hand-drawn illustration name.
items = client.illustrations.search("creative")
print(items)Create and Wait
OpenAPI enforces active export concurrency per account.
If your account already has two active export tasks, exports.create returns 422 OPEN_API_EXPORT_CONCURRENCY_LIMIT_EXCEEDED.
created = client.exports.create(
{
"editorState": editor_state,
"ratio": "9:16",
"scale": 0.6,
"fps": 30,
"format": "mp4",
}
)
print(created.duration_seconds, created.billed_standard_seconds)
done = client.exports.wait(created.task_id, timeout=600, poll_interval=2)
print(done.status, done.output_url)duration_seconds is the real export duration. billed_standard_seconds is the billing unit.
Project Workflow
project = client.projects.create(
{
"title": "Launch draft",
"editorState": editor_state,
}
)
with open("hero.png", "rb") as fh:
asset = client.uploads.upload(
fh.read(),
filename="hero.png",
content_type="image/png",
project_id=project.project_id,
)
client.projects.sync(
project.project_id,
{
"editorState": {
**editor_state,
"assets": {
**editor_state.get("assets", {}),
"hero": {
"type": "image",
"remoteUrl": asset.file_url,
"remoteKey": asset.file_key,
},
},
}
},
)
created_from_project = client.projects.create_export(
project.project_id,
{
"ratio": "9:16",
"scale": 0.6,
"fps": 30,
"format": "mp4",
},
)
done = client.exports.wait(created_from_project.task_id, timeout=600, poll_interval=2)
print(done.project_id, done.status)List Exports
page = client.exports.list(
page_size=20,
page_cursor=None,
created_by_api_key_id=None,
)
print(len(page.items), page.next_page_cursor)
print(page.items[0].created_by_api_key_id if page.items else None)Verify and Parse Webhook
import json
from indream import verify_export_webhook_request
from indream.types import ExportWebhookEvent
raw_body = request.get_data(as_text=True)
is_valid = verify_export_webhook_request(
webhook_secret=WEBHOOK_SECRET,
raw_body=raw_body,
headers=request.headers,
max_skew_seconds=300, # optional
)
if not is_valid:
raise ValueError("Invalid webhook signature")
event = ExportWebhookEvent.model_validate(json.loads(raw_body))
print(event.event_type)
print(
event.task.task_id,
event.task.status,
event.task.duration_seconds,
event.task.billed_standard_seconds,
)event_type values are EXPORT_STARTED, EXPORT_COMPLETED, EXPORT_FAILED.
event.task has the same shape as client.exports.get(task_id) result.
duration_seconds is the real export duration, while billed_standard_seconds is the billing unit.
verify_export_webhook_request validates both signature headers and timestamp skew window.
Validate Editor State
capabilities = client.editor.capabilities()
print([preset.id for preset in capabilities.caption_animations.in_])
result = client.editor.validate(editor_state)
if not result.valid:
for err in result.errors:
print(err.code, err.path, err.message)client.editor.validate(...) and client.exports.create(...) perform local editor-state schema checks before sending the request.
If the payload is invalid, the SDK raises ValidationError immediately.
Async Client
import asyncio
from indream import AsyncIndreamClient
async def main() -> None:
client = AsyncIndreamClient(api_key="<YOUR_API_KEY>")
created = await client.exports.create(
{
"editorState": editor_state,
"ratio": "9:16",
"scale": 0.6,
"fps": 30,
"format": "mp4",
}
)
done = await client.exports.wait(created.task_id, timeout=600, poll_interval=2)
print(done.status, done.output_url)
await client.aclose()
asyncio.run(main())Exceptions
AuthError: invalid credentials or forbidden scope.ValidationError: schema or semantic payload issue.RateLimitError: request throttled.APIError: non-specialized API error.
Resources
For source code, issues, and contributions, visit our GitHub repository. Install the latest Python package from indream-client.
Last updated on