Avatar handle with a hyphen is rejected: the valid pattern
Sume avatar handles allow letters, digits, periods and underscores, 2 to 30 characters. A hyphen fails the pattern. Check yours in Python first.
An avatar handle such as product-host does not match the pattern in the Sume OpenAPI: only letters, digits, periods and underscores are allowed, 2 to 30 characters, and a period or underscore cannot be first, last or doubled. Use product_host instead. A leading @ is optional: Sume lowercases the handle and stores it without the @.
What the pattern accepts
The Avatar 1.0 create route (POST /v1/avatar-1.0/generate) takes a top-level avatar_handle. The OpenAPI pattern for face swap and TTS is the same grammar: ^@?(?![._])(?!.*[._]$)(?!.*[._]{2})[A-Za-z0-9._]{2,30}$. The table runs ten candidates through that regex.
| Candidate | Result | Reason or stored form |
|---|---|---|
| product_host | accepted | stored as product_host |
| product-host | rejected | hyphen is not in the allowed set |
| @Product.Host | accepted | stored as product.host |
| brand..host | rejected | consecutive periods |
| .host | rejected | starts with a period or underscore |
| host_ | rejected | ends with a period or underscore |
| a | rejected | shorter than 2 characters |
| sume_clawra | accepted | stored as sume_clawra |
| host.v2 | accepted | stored as host.v2 |
| xxxxxx... (31 x's) | rejected | longer than 30 characters |
Check handles before you submit
Add a local check in your import script so a bad handle fails in your code and not in a batch of 200 creates. The pattern is the one from the docs; keep it in sync if the OpenAPI changes.
import re
HANDLE = re.compile(r"^@?(?![._])(?!.*[._]$)(?!.*[._]{2})[A-Za-z0-9._]{2,30}$")
def to_handle(name: str) -> str:
"""Turn a brand name into a legal handle, or raise."""
cand = re.sub(r"[^A-Za-z0-9._]+", "_", name.strip()).strip("._")
cand = re.sub(r"[._]{2,}", "_", cand)
if not HANDLE.match(cand):
raise ValueError(f"no legal handle for {name!r}")
return cand.lower()
print(to_handle("Product Host")) # product_host
print(to_handle("brand-host.v2")) # brand_host.v2Limits and gotchas
- The handle is the name you reuse later in
avatar_handleon talking videos, so pick one you will not want to change. - Handles must be normalized by you if you compare them:
@Product.Hostandproduct.hostare the same avatar. - The same grammar applies when you pass
avatar_handleto TTS or face swap, so one validator covers all three. - Creating the avatar is a fixed per-avatar price, listed in
GET /v1/catalog.
Sources
Related posts
More in Sume Avatar 1.0
- Face swap beta, 9-second clip: you reserve the 15-second price
Sume's Avatar Face Swap beta reserves the maximum 15-second source price whatever your clip length: $2.76 at standard, $3.675 at plus, $8.25 at max.
- Griffin-Lite's 0.27 to 0.59 s latency in 25 fps frames vs Sume clips
Tavus reports Griffin-Lite video latency of 0.43 s average (0.27 best, 0.59 worst). At 25 fps that is 7 to 15 frames. Sume renders recorded clips.
- Narrate a listing in your avatar's voice: TTS with avatar_handle
Sume TTS 1.0 can speak with the voice of a ready avatar if you pass avatar_handle. A 1,200-character listing script costs $0.057.
- One 15-second avatar script in 9:16, 1:1 and 16:9: cost of all three
Rendering one 15 s script in three aspect ratios is three jobs: $8.28 at standard, $11.025 at plus, $24.75 at max. Aspect ratio does not change the price.
Written by Sume