SayMaker (saymaker v0.1.0)

Copy Markdown View Source

Generate images and video on SayMaker from Elixir.

{:ok, url} = SayMaker.generate("matte black ceramic mug on pale oak, soft window light")
{:ok, clip} = SayMaker.generate_video("a fox trotting through fresh snow", duration: 6)

One API key runs the whole shelf on your own credits: Veo 3.1, Kling 3.0, Seedance 2.0, MiniMax H3, Nano Banana 2, GPT Image 2.5, Seedream 5.0 and more. Pass api_key: or set SAYMAKER_API_KEY; create a key at https://saymaker.ai/settings/apikeys.

Failures are {:error, reason, message} where reason is :auth, :quota, :plan, :busy, :rejected, :timeout or :other.

Uses only :httpc from OTP and the standard JSON module; no dependencies.

Summary

Functions

Maps a refusal message to the reason that says what to do next.

Generates one image, or edits :image_url, and returns its URL.

Generates one clip, or animates :image_url as the first frame, and returns its URL.

Model id to the routing field the API expects next to it. Unlisted ids go as "kie".

Types

reason()

@type reason() :: :auth | :quota | :plan | :busy | :rejected | :timeout | :other

result()

@type result() :: {:ok, String.t()} | {:error, reason(), String.t()}

Functions

classify(message, data \\ nil)

@spec classify(String.t(), term()) :: reason()

Maps a refusal message to the reason that says what to do next.

generate(prompt, opts \\ [])

@spec generate(String.t(), keyword()) :: result()

Generates one image, or edits :image_url, and returns its URL.

Options: :model (default "saymaker-image-v1", or "nano-banana-2-lite" for an edit), :image_url, :aspect_ratio ("1:1", "16:9", "9:16", "4:3", "3:4"), :api_key, :poll_ms, :timeout_ms (default 75 minutes, which covers the free-account queue). For an edit, the prompt names the change and what must stay.

generate_video(prompt, opts \\ [])

@spec generate_video(String.t(), keyword()) :: result()

Generates one clip, or animates :image_url as the first frame, and returns its URL.

Options: :model (default "minimax-h3-fast", the one a free account can run; "veo-3-1", "kling-3-0" and "seedance-2" need a plan or a credit pack), :image_url, :duration (seconds), :resolution ("480p", "720p", "1080p"), :aspect_ratio (default "16:9"), :sound (default true), :api_key, :poll_ms, :timeout_ms (default 90 minutes).

models()

@spec models() :: %{required(String.t()) => String.t()}

Model id to the routing field the API expects next to it. Unlisted ids go as "kie".