SegmindSegmind / Docs

Python SDK

Run any Segmind model from Python. Async-by-default run(), explicit sync run_sync(), submit/poll handles for long jobs, and a normalized LLM chat() — all over the v2 async gateway.

The Segmind Python SDK is a thin client over the AI Gateway. As of 1.1.0 it is async-by-default: run() submits to the v2 async API, polls for you, and returns the finished result. A blocking v1 call is still available as run_sync().

segmind.pixelflows does not work in 1.1.0. The namespace ships and the package README refers to it, but run(), get_status() and poll() all raise AttributeError on the first call. It is a known defect on our side — not a usage error, and no argument combination avoids it. Call published PixelFlow workflows over REST with the Workflow API until a fix ships.

Install

pip install "segmind>=1.1.0"

1.1.0 is a breaking release. run() is now async (v2). The old blocking behaviour moved to run_sync(), and run_async() was removed — call run() instead. If you're upgrading from 1.0.x, see Migrating from 1.0.x.

Set your API key once via the environment:

export SEGMIND_API_KEY="YOUR_API_KEY"

The SDK reads SEGMIND_API_KEY automatically. Grab a key from the API Keys page.

Sync vs. async — which to use?

  • run() (async, default) — submits to v2, polls, and returns the result. Best for anything that can take more than a few seconds, and the right default for almost all models. Has a built-in 600 s deadline.
  • run_sync() (sync) — a single blocking v1 HTTP call. Fine for fast models (< 60 s) when you want the raw bytes back immediately. v1 is in maintenance mode.
  • submit_async() (handle) — submit now, poll later with your own deadline and cadence. Use this for long video/LLM jobs that may exceed 600 s, for fire-and-forget patterns, or to fan out many requests in parallel.

Quick start

import segmind

# Submit to v2, poll until COMPLETED, return the result body.
result = segmind.run("seedream-4.5", prompt="a red rose on a wooden table")
print(result["output"])  # URL to the generated image
import segmind

# Single blocking v1 call — returns a raw httpx.Response.
response = segmind.run_sync("seedream-4.5", prompt="a red rose on a wooden table")
with open("rose.jpg", "wb") as f:
    f.write(response.content)

API

segmind.run(slug, **params) -> dict

Async by default. Submits to POST /v2/{slug}, polls until the request reaches COMPLETED, and returns the final response body as a dict. Polls every 1 s with a 600 s deadline.

result = segmind.run("seedream-4.5", prompt="a sunset over the ocean")
print(result["output"])

run() forwards every keyword to the model body, so it does not accept timeout or interval arguments (a model could legitimately have a param named timeout). For a custom deadline or poll cadence, use submit_async() + job.wait(timeout=…, interval=…).

segmind.run_sync(slug, **params)

Synchronous, single blocking call to POST /v1/{slug}. Returns the raw httpx.Response — use .content for binary output (images, audio) or .json() for structured responses.

response = segmind.run_sync("sdxl1.0-newreality-lightning", prompt="a cyberpunk city")
with open("city.jpg", "wb") as f:
    f.write(response.content)

segmind.submit_async(slug, **params) -> AsyncJob

Submits a v2 request and returns an AsyncJob handle immediately, without waiting for the result. Use it to control the poll deadline/cadence, to keep the request_id, or to run other work while the job processes.

job = segmind.submit_async("seedance-2.0", prompt="a sunset timelapse")
print(job.request_id)          # e.g. "2c7f59ea-13f1-402c-9353-915a2b5a2124"
result = job.wait(timeout=600) # block until done

AsyncJob

The handle returned by submit_async().

Attribute / methodReturnsDescription
.request_idstrUnique id for the submitted request.
.status_urlstrLightweight status endpoint (no payload).
.response_urlstrFull result endpoint.
.status()dictCurrent status body without blocking. status is one of QUEUED, PROCESSING, COMPLETED, FAILED.
.result()dictFinal response body. Only meaningful once COMPLETED.
.wait(timeout=600.0, interval=1.0)dictBlock until a terminal state and return the result. Raises InferenceFailed / InferenceTimeout.
import time
import segmind

job = segmind.submit_async("seedance-2.0", prompt="a sunset timelapse")

# Manual polling, if you want it:
while job.status()["status"] not in ("COMPLETED", "FAILED"):
    time.sleep(2)

result = job.result()

Error handling

run() and AsyncJob.wait() raise on failure:

ExceptionRaised whenAttributes
InferenceFailedThe request reached FAILED..detail (server error string), .status_body (raw status payload)
InferenceTimeoutwait() exceeded its timeout before a terminal state. The job may still be running server-side — re-fetch to recover..request_id, .elapsed_s
SegmindErrorBase class — transport/auth errors (401/404/5xx)..status, .detail
import segmind
from segmind import InferenceFailed, InferenceTimeout

try:
    result = segmind.run("seedream-4.5", prompt="a red rose")
except InferenceFailed as e:
    print(f"Model failed: {e.detail}")
except InferenceTimeout as e:
    print(f"Still running after {e.elapsed_s:.0f}s — request {e.request_id}")

Worked examples

Fast image model

For a quick image model the defaults are all you need — run() typically returns after a single poll.

import segmind

result = segmind.run("seedream-4.5", prompt="a red rose on a wooden table, studio lighting")
print(result["output"])  # https://images.segmind.com/generations/...jpeg

Slow video model

Video generation can run for several minutes. Because run() caps the wait at 600 s, use submit_async() and pass a larger timeout (and a slower interval to reduce poll traffic):

import segmind
from segmind import InferenceFailed, InferenceTimeout

job = segmind.submit_async("seedance-2.0", prompt="a sunset timelapse over the ocean")
print(f"Submitted {job.request_id}")

try:
    result = job.wait(timeout=900, interval=5)  # up to 15 min, poll every 5s
    print(result["output"])  # URL to the generated video
except InferenceTimeout as e:
    print(f"Not done after {e.elapsed_s:.0f}s — poll {job.status_url} later")
except InferenceFailed as e:
    print(f"Failed: {e.detail}")

For truly long-running or fire-and-forget jobs, register a webhook instead of polling — you'll be notified when the result is ready.

LLM chat

For text/LLM models, chat() returns a normalized ChatResponse with a provider-agnostic .text. It's async-by-default like run(), with chat_sync() and submit_chat() counterparts.

import segmind

reply = segmind.chat("gpt-5.5", prompt="Write a haiku about the sea")
print(reply.text)

ChatResponse exposes .text, .json(), .tool_calls, .usage, and .raw. Streaming is not supported by the gateway. See the v2 async reference for the underlying response shape.

Beyond inference

run() and chat() are the SDK's main event, but it also ships a handful of namespaces that wrap the account-level APIs. They are useful and, until now, undocumented.

segmind.models.list()

Every model on the platform, in one call. This is the only place the catalog is available programmatically — there is no REST endpoint for it.

import segmind

catalog = segmind.models.list()["Inference Model Information List"]
print(len(catalog))
print(catalog[0]["slug"], catalog[0]["type"])

Each entry carries slug, title, type (imageToVideo, textToImage, …), description, average_cost, latency, parameters_schema, and flags such as is_new and is_depreciated. Filtering on is_depreciated is the cheapest way to check whether a slug you depend on is on its way out.

segmind.generations

Your own request history — the same data behind Generations in the console.

page = segmind.generations.list(page=1)
print(page["total_records"], page["total_pages"], page["per_page"])
for row in page["data"]:
    print(row["model_name"], row["created_at"], row["generation_url"])

# or the newest few for one model
segmind.generations.recent("p-image")

list() is paginated and returns total_records, total_pages, current_page, per_page, has_next, has_previous and data. recent() takes a model slug and returns data with request_id, generation_url, created_at and status.

segmind.files.upload(file_paths)

Uploads local files and returns reusable URLs — the Segmind Storage API, with the base64 encoding done for you.

result = segmind.files.upload(["portrait.jpg"])
url = result["file_urls"][0]

segmind.run("some-image-to-image-model", image=url)

Takes a list, returns one URL per file in the same order. The size and pixel-count limits are the same as the underlying API.

segmind.webhooks

Manage webhook registrations without going through the console.

CallDoes
webhooks.get()list your registrations — [] if you have none
webhooks.add(webhook_url, event_types)register an endpoint
webhooks.update(webhook_id, webhook_url, event_types)change one
webhooks.delete(webhook_id)remove one
webhooks.logs(webhook_id)delivery history for one registration

See Webhooks for the event names.

segmind.accounts and segmind.finetune expose no methods. Both namespaces import and both are empty — reaching for anything on them raises AttributeError. Read your credit balance over REST instead.

segmind.pixelflows is present but non-functional in 1.1.0, as noted at the top of this page — run() and get_status() reject every argument they are given.

Migrating from 1.0.x

1.1.0 flips the default verb to async. Update calls as follows:

1.0.x1.1.0
segmind.run(slug, ...) (sync)segmind.run_sync(slug, ...)
segmind.run_async(slug, ...)segmind.run(slug, ...)
segmind.submit_async(slug, ...) (unchanged)

run_async() was removed with no alias — importing or calling it raises an error. There is no behavioural change to submit_async().

See also

On this page