Quickstart
An account, a key, and one changed line. The panel on the right is the request you will end up sending.
Create an account
Sign in with an email address at /login. There is no anonymous generation on this platform — every completion is attributable to an account, including the free ones.
429 free_allowance_exhausted until it renews or the account is upgraded — see Access & pricing. Build your retry logic accordingly: that one is not retryable.Create an API key
Go to API keys and create one. The full value is shown once, at creation — only a SHA-256 hash is stored, so a lost key is rotated, never recovered.
Use a ad_test_ key while you are wiring things up and a ad_live_ key when you mean it. Details on Authentication.
Put it in the environment
export AD_API_KEY="ad_live_…"Never in browser JavaScript, a mobile binary, or a committed file: a key carries the full spending authority of the account that owns it.
Change one base_url
The inference surface is OpenAI-compatible, so the official SDKs work unmodified. Point them at https://adversariallm.ai/v1.
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["AD_API_KEY"],
base_url="https://adversariallm.ai/v1",
)
completion = client.chat.completions.create(
model="example-model",
messages=[
{
"role": "user",
"content": "Summarise this advisory in two lines.",
},
],
)
print(completion.choices[0].message.content)import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.AD_API_KEY,
baseURL: "https://adversariallm.ai/v1",
});
const completion = await client.chat.completions.create({
"model": "example-model",
"messages": [
{
"role": "user",
"content": "Summarise this advisory in two lines."
}
]
});
console.log(completion.choices[0].message.content);No SDK? The same call with curl:
curl -sS https://adversariallm.ai/v1/chat/completions \
-X POST \
-H "Authorization: Bearer $AD_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"example-model","messages":[{"role":"user","content":"Summarise this advisory in two lines."}]}'Stream it
Set stream: true to get text/event-stream frames terminated by data: [DONE]. Only completion frames are emitted — nothing else is mixed into the stream, so a naive parser cannot trip over one.
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["AD_API_KEY"],
base_url="https://adversariallm.ai/v1",
)
stream = client.chat.completions.create(
model="example-model",
messages=[
{
"role": "system",
"content": "You are terse.",
},
{
"role": "user",
"content": "Explain CVE triage.",
},
],
stream_options={
"include_usage": True,
},
max_tokens=512,
stream=True,
)
for chunk in stream:
if not chunk.choices:
continue # final usage frame
piece = chunk.choices[0].delta.content
if piece:
print(piece, end="", flush=True)