Quickstart
Create an ASOP token and call chat, KREA2, REDQW21 (Qwen Image 2.1), and listed reference-to-video models. Credits share the Create-page wallet.
Get your API token
Open asop.uk/api and generate a token. Format is asop- plus 32 hex characters, for example asop-a1b2…. asop.uk/api
Save it locally or download the JSON. The list on the site stays masked; use View to reveal again. Revoke it if it leaks.
Set up your API key
Export it in your shell:
export ASOP_API_KEY='asop-your-token-here'
Or add it to a .env file:
ASOP_API_KEY=asop-your-token-here
Install the SDK
ASOP is OpenAI-compatible. Use the OpenAI SDK, or skip this step and call HTTP directly.
pip install openainpm install openaiSend your first request
Base URL: https://asop.uk/api/v1. Chat uses model prompt-assist.
import os
from openai import OpenAI
client = OpenAI(
api_key=os.getenv("ASOP_API_KEY"),
base_url="https://asop.uk/api/v1",
)
completion = client.chat.completions.create(
model="prompt-assist",
messages=[
{"role": "system", "content": "You write cinematic still prompts."},
{"role": "user", "content": "A wet neon alley at 2 a.m., rain on asphalt."},
],
)
print(completion.choices[0].message.content)import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.ASOP_API_KEY,
baseURL: "https://asop.uk/api/v1",
});
const completion = await client.chat.completions.create({
model: "prompt-assist",
messages: [
{ role: "system", content: "You write cinematic still prompts." },
{ role: "user", content: "A wet neon alley at 2 a.m., rain on asphalt." },
],
});
console.log(completion.choices[0].message.content);curl https://asop.uk/api/v1/chat/completions \
-H "Authorization: Bearer $ASOP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "prompt-assist",
"messages": [
{"role": "system", "content": "You write cinematic still prompts."},
{"role": "user", "content": "A wet neon alley at 2 a.m., rain on asphalt."}
]
}'Message roles: system (instructions), user (prompt), assistant (prior turns). Vision is supported: put image_url parts on a user message for reverse-prompt work.
Generate an image
KREA2 and REDQW21 (Qwen Image 2.1) are async: they return a job id — poll GET /jobs/{id}. Official Image3 / Dream5 are delisted.
import os
from openai import OpenAI
client = OpenAI(
api_key=os.getenv("ASOP_API_KEY"),
base_url="https://asop.uk/api/v1",
)
![]()
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.ASOP_API_KEY,
baseURL: "https://asop.uk/api/v1",
});
const img = await client.images.generate({
model: "heishou-krea2",
prompt: "Portrait still, wet neon alley, 2:3, cinematic grain",
size: "1024x1536",
image_resolution: "6MP",
krea2Mode: "story",
});
console.log(img.id, img.status);curl https://asop.uk/api/v1/images/generations \
-H "Authorization: Bearer $ASOP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "heishou-krea2",
"prompt": "Portrait still, wet neon alley, 2:3, cinematic grain",
"size": "1024x1536",
"aspect_ratio": "2:3",
"image_resolution": "6MP",
"krea2Mode": "story"
}'Reference-to-video
POST /files first, then POST /videos/generations. Jobs are async. Poll GET /jobs/{id}; output.url is a 1-hour signed link.
import os, time, requests
base = "https://asop.uk/api/v1"
headers = {"Authorization": f"Bearer {os.environ['ASOP_API_KEY']}"}
up = requests.post(
f"{base}/files",
headers=headers,
files={"file": ("ref.png", open("ref.png", "rb"), "image/png")},
data={"purpose": "reference"},
)
file_id = up.json()["id"]
job = requests.post(f"{base}/videos/generations", headers=headers, json={
"model": "heishou-h3",
"prompt": "Slow push-in, cinematic grain, 2:3",
"duration": 8,
"aspect_ratio": "2:3",
"images": [file_id],
}).json()
while True:
row = requests.get(f"{base}/jobs/{job['id']}", headers=headers).json()
if row["status"] in ("completed", "failed"):
break
time.sleep(4)
print(row.get("output") or row.get("error"))curl https://asop.uk/api/v1/files \
-H "Authorization: Bearer $ASOP_API_KEY" \
-F "[email protected]" \
-F "purpose=reference"
curl https://asop.uk/api/v1/videos/generations \
-H "Authorization: Bearer $ASOP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "heishou-h3",
"prompt": "Slow push-in, cinematic grain, 2:3",
"duration": 8,
"aspect_ratio": "2:3",
"images": ["file_YOUR_ID"]
}'
curl https://asop.uk/api/v1/jobs/JOB_ID \
-H "Authorization: Bearer $ASOP_API_KEY"Models you can call
All nine IDs work on this relay. Credits match the Create estimate (same wallet, live quote).
List models: GET https://asop.uk/api/v1/models with the same Bearer token.
Enable streaming (optional)
stream = client.chat.completions.create(
model="prompt-assist",
messages=[{"role": "user", "content": "Write a 4-beat video prompt."}],
stream=True,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")const stream = await client.chat.completions.create({
model: "prompt-assist",
messages: [{ role: "user", content: "Write a 4-beat video prompt." }],
stream: true,
});
for await (const chunk of stream) {
const t = chunk.choices?.[0]?.delta?.content;
if (t) process.stdout.write(t);
}curl https://asop.uk/api/v1/chat/completions \
-H "Authorization: Bearer $ASOP_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"prompt-assist","stream":true,"messages":[{"role":"user","content":"Hello"}]}'Credits
API calls debit the same credit wallet as the Create page. The Credits ledger tags each row as Demo or API and names the model. Failed generations are refunded. 402 means the wallet is empty.
Next steps
API Reference
Endpoints, parameters, and error codes.
Create a token
Generate an asop-xxxx key and download the Agent Skill.
Agents: this page is also Markdown. Index: Markdown · /docs/llms.txt.