SDKs & Client Libraries

Use the OpenAI, Anthropic, or Google SDK against Atlas Cloud, plus copy-paste clients for image, video, and audio generation in Python and Node.js.

Atlas Cloud does not ship its own SDK, and for language models you do not need one — the API speaks the formats existing SDKs already use. For media generation, this page has a small client you can copy into your project.

What you're callingHow
Language modelsPoint the OpenAI, Anthropic, or Google SDK at Atlas Cloud
Image, video, audio, 3DPlain HTTP against the asynchronous endpoints — client below
From a terminal or CIThe CLI
From an AI-assisted IDEThe MCP Server

Language models

Change the base URL and the API key. Everything else stays the same.

pip install openai
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["ATLASCLOUD_API_KEY"],
    base_url="https://api.atlascloud.ai/v1",
)

response = client.chat.completions.create(
    model="deepseek-ai/deepseek-v3.2",
    messages=[{"role": "user", "content": "Explain HTTP vs HTTPS"}],
)
print(response.choices[0].message.content)

Models differ in which protocol they accept — some only work with Messages, others only with Responses. Check the model's API reference before assuming Chat Completions works. See LLM API Protocols.

Media generation client

Image, video, audio, and 3D generation are asynchronous: submit, then poll. Here is a complete minimal client.

import os
import time
import requests

API_KEY = os.environ["ATLASCLOUD_API_KEY"]
BASE = "https://api.atlascloud.ai/api/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

# The endpoint is chosen by output type: 3D uses image; speech, music and transcription all use audio
ENDPOINTS = {
    "image": f"{BASE}/model/generateImage",
    "video": f"{BASE}/model/generateVideo",
    "audio": f"{BASE}/model/generateAudio",
}
TERMINAL = {"completed", "succeeded", "failed", "timeout"}


def submit(kind: str, model: str, **params) -> str:
    """Submit a job and return its prediction ID. Parameters go at the top level, not inside an `input` object."""
    response = requests.post(
        ENDPOINTS[kind],
        headers=HEADERS,
        json={"model": model, **params},
        timeout=60,
    )
    response.raise_for_status()
    return response.json()["data"]["id"]


def wait(prediction_id: str, timeout: int = 600) -> dict:
    """Poll until the job reaches a terminal state, backing off as it goes."""
    deadline = time.time() + timeout
    delay = 2.0

    while time.time() < deadline:
        response = requests.get(
            f"{BASE}/model/prediction/{prediction_id}",
            headers=HEADERS,
            timeout=30,
        )
        response.raise_for_status()
        data = response.json()["data"]

        if data.get("status") in TERMINAL:
            if data["status"] in ("failed", "timeout"):
                raise RuntimeError(f"Generation failed: {data.get('error') or data['status']}")
            return data

        time.sleep(delay)
        delay = min(delay * 1.5, 10.0)

    raise TimeoutError(f"Job {prediction_id} did not finish within {timeout}s")


def upload(path: str) -> str:
    """Upload a local file and return a URL usable in a generation request."""
    with open(path, "rb") as f:
        response = requests.post(
            f"{BASE}/model/uploadMedia", headers=HEADERS, files={"file": f}, timeout=600
        )
    response.raise_for_status()
    data = response.json()["data"]
    return data.get("download_url") or data.get("url")


if __name__ == "__main__":
    pid = submit("image", "MODEL_ID", prompt="a ceramic mug on a linen backdrop")
    result = wait(pid)
    print(result["outputs"][0])

Two things this client gets right that are easy to get wrong:

  1. Parameters go at the top level, next to model — not wrapped in an input object.
  2. For transcription and lyric models, outputs[0] is text, not a URL. Do not blindly download it. See Audio Models.

Production notes

  • Prefer webhooks over polling for video, which can take minutes. See Webhooks.
  • Retry on 429, 500, 503, 504 with exponential backoff. Do not retry 400, 401, 402, 403. See Errors & Rate Limits.
  • Be careful retrying submissions. A timed-out submit may still have been accepted, and a blind retry creates a second billable job. Submit asynchronously and poll instead.
  • Log X-Request-ID from every response — it is what support needs to trace a call.

Community libraries

Community-maintained wrappers are listed in awesome-atlas-cloud-integrations. They are maintained independently — verify what a wrapper does before using it in production.

Last updated on

On this page