OpenAI Python SDK: Carpe Diem base_url, cdm_ key, real cost

This tutorial is for calling Carpe Diem from a Python script, with the OpenAI SDK you already use: chat, model list, model switch, streaming, cost readout. You install one package, openai==3.36.0, in a venv. Then two fields are enough: base_url set to https://carpe-diem.xyz/api/operator/v1 and a cdm_ key. Our 22 October 2026 run got pong from llama-3.3-70b for 524 micro-USDC; the same client listed 392 models.

Illustration generated with seedream-v5-lite on Carpe Diem.
What you need
Nothing besides Python, a venv, the pinned OpenAI SDK, and a Carpe Diem key. No Carpe Diem CLI, no house SDK.
- A Carpe Diem account with credits or a prepaid account, and a
cdm_key (API Keys tab of the buyer dashboard). - Python 3.10 or newer (
openai==3.36.0requires it). pipinside a venv, to pinopenai==3.36.0.
When you are done, you can: send a chat.completions.create (step 3), list ids via models.list() (step 3), read x-carpe-cost-usdc-micro (step 4), switch from llama-3.3-70b to claude-haiku-5-5 by changing one string (step 5), and stream a haiku (step 6).
Step 1: create a cdm_ key
Open Credits & keys, API Keys tab. Keys start with cdm_ and are shown only once. Choose how the key pays (Credits or Prepaid), optionally a name, then Create a key.
Credits: usage balance, 1 credit = 0,01 $, no withdrawal. Prepaid: an account you own; the protocol deducts only the cost of each call, withdrawal possible. Both settle in USDC on Base (guide, §4.1). A third rail, x402, pays from a wallet without a cdm_ key; this tutorial does not cover that rail.

Copy it immediately into a secrets manager: it will not be shown again. In the tutorial shell:
export OPENAI_API_KEY=cdm_your_key_here
To try a model without code, use Create Hub.
Step 2: install openai 3.36.0
python3 -m venv .venv
.venv/bin/pip install openai==3.36.0
We did not test any other version of the package. The OpenAI client sends POST /chat/completions under base_url. For Carpe Diem, base_url must therefore already include /v1:
https://carpe-diem.xyz/api/operator/v1
Not https://carpe-diem.xyz/api/operator: that is the Anthropic adapter URL, a different protocol. The SDK guide states it at the top of the page, just above the OpenAI Python example.

Step 3: send the first message
File hello.py (the client is recreated there, as in every snippet):
import os
from openai import OpenAI
client = OpenAI(
base_url="https://carpe-diem.xyz/api/operator/v1",
api_key=os.environ["OPENAI_API_KEY"],
)
response = client.chat.completions.create(
model="llama-3.3-70b",
messages=[{"role": "user", "content": "Reply with the exact word: pong"}],
max_tokens=16,
)
print(response.choices[0].message.content)
print("model:", response.model)
print("usage:", response.usage)
.venv/bin/python hello.py
Output we got:
pong
model: llama-3.3-70b
usage: CompletionUsage(completion_tokens=2, prompt_tokens=1675, total_tokens=1677, …)
Two output tokens, but 1675 on input for a six-word sentence. On our two calls to llama-3.3-70b with this prompt, 1675 then 1695 input tokens were billed (2714 on Haiku). The origin of that preamble is not documented. max_tokens=16 caps output only.
To check that an id exists before writing the rest:
import os
from openai import OpenAI
client = OpenAI(
base_url="https://carpe-diem.xyz/api/operator/v1",
api_key=os.environ["OPENAI_API_KEY"],
)
models = client.models.list()
ids = sorted(m.id for m in models.data)
print("count:", len(ids))
print("has llama-3.3-70b:", "llama-3.3-70b" in ids)
print("has claude-haiku-5-5:", "claude-haiku-5-5" in ids)
Output: 392 ids, both True. models.list() calls GET /v1/models with the same key: no second client.
Step 4: read the call cost
The SDK JSON body does not carry the price. Carpe Diem puts it in HTTP headers, in micro-USDC (1 USDC = 1 000 000 micro-USDC), non-streaming only. That is documented in the SDK guide, X-Carpe-* header table. with_raw_response exposes them; raw.parse() returns the usual object.
File cost.py:
import os
from openai import OpenAI
client = OpenAI(
base_url="https://carpe-diem.xyz/api/operator/v1",
api_key=os.environ["OPENAI_API_KEY"],
)
raw = client.chat.completions.with_raw_response.create(
model="llama-3.3-70b",
messages=[{"role": "user", "content": "Reply with the exact word: pong"}],
max_tokens=16,
)
headers = raw.headers
print("x-carpe-cost-usdc-micro:", headers.get("x-carpe-cost-usdc-micro"))
print("x-carpe-input-tokens:", headers.get("x-carpe-input-tokens"))
print("x-carpe-output-tokens:", headers.get("x-carpe-output-tokens"))
print("x-carpe-available-credits:", headers.get("x-carpe-available-credits"))
print("x-carpe-cached-tokens:", headers.get("x-carpe-cached-tokens"))
response = raw.parse()
print("text:", response.choices[0].message.content)
print("usage:", response.usage)
Headers read on this call:
x-carpe-cost-usdc-micro: 524x-carpe-input-tokens: 1675x-carpe-output-tokens: 2x-carpe-available-credits: your remaining balance, in creditsx-carpe-cached-tokens: absent (Nonein the SDK)
524 micro-USDC. At 0,311 $ / 1,24 $ per million tokens (31,1 / 124 cr/M on /models, 1 credit = 0,01 $), 1675 × 0,311 $ / M + 2 × 1,24 $ / M = 523 micro-USDC. 523 calculated, 524 billed: the amount appears rounded up to the next micro-USDC.
Step 5: switch model with a string
Same client, different id. The public catalog shows prices in credits per million (1 credit = 0,01 $): llama-3.3-70b at 31,1 / 124 cr/M, claude-haiku-5-5 at 4,5 / 22,2 cr/M.

File switch_model.py:
import os
from openai import OpenAI
client = OpenAI(
base_url="https://carpe-diem.xyz/api/operator/v1",
api_key=os.environ["OPENAI_API_KEY"],
)
for model in ("llama-3.3-70b", "claude-haiku-5-5"):
raw = client.chat.completions.with_raw_response.create(
model=model,
messages=[{"role": "user", "content": "Reply with the exact word: pong"}],
max_tokens=16,
)
text = raw.parse().choices[0].message.content
print(model)
print(" text:", text)
print(" cost-usdc-micro:", raw.headers.get("x-carpe-cost-usdc-micro"))
print(" in:", raw.headers.get("x-carpe-input-tokens"), "out:", raw.headers.get("x-carpe-output-tokens"))
Both returned pong. On this second pass, llama-3.3-70b cost 530 micro-USDC for 1695 + 2 tokens, in the same range as the 524 / 1675 of step 4. claude-haiku-5-5 was billed 14 micro-USDC, with 2714 + 4 tokens in the headers. At the catalog rate 4,5 / 22,2 cr/M, those tokens would come to about 123 micro-USDC: the gap is unexplained (we did not read x-carpe-cached-tokens on that call). Trust the header, not the hand calculation.
Ids are copied from /models. llama-3.3-70b-typo was not rewritten to llama-3.3-70b: paste the id from the card.
Step 6: turn on streaming
Keep the chunk.choices check: the SDK guide uses it, and a chunk with no choices would crash on chunk.choices[0].
import os
from openai import OpenAI
client = OpenAI(
base_url="https://carpe-diem.xyz/api/operator/v1",
api_key=os.environ["OPENAI_API_KEY"],
)
stream = client.chat.completions.create(
model="llama-3.3-70b",
messages=[{"role": "user", "content": "Write a haiku about the sea."}],
max_tokens=64,
stream=True,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
print()
Text received, token by token:
Crashing waves ascend
Foam kisses the sandy shore
Ocean's gentle song
When streaming, X-Carpe-Cost-Usdc-Micro is not sent (SDK docs). To record cost, stay on the non-streaming call.
If it fails
401 AUTH_REQUIRED. With OPENAI_API_KEY=cdm_invalid, the SDK raised openai.AuthenticationError: Error code: 401 - {'error': 'Unauthorized', 'code': 'AUTH_REQUIRED'}. Incomplete key, bad copy, or the env var not exported in this shell. An export in a terminal does not reach an IDE launched from the dock.
400 MODEL_ERROR. model="llama-3.3-70b-typo" returned: This model is no longer available upstream. Try a newer version of the same model. The message talks about an upstream retirement; here it was a typo. Check the id on /models or via client.models.list().
URL without /v1. See step 2.
Going further
The same base_url with /v1 replaced by /router sends the call to the best-price router: same key, same body. We did not replay hello.py on /router in this run.
For an agent in the terminal rather than a script, we already wired OpenCode: Kimi K3 and Claude Fable in OpenCode.
To try a model without writing hello.py, open Create Hub, then come back and paste the id into model=.
Test run on 22 October 2026 with openai==3.36.0 and a funded test key. The snippets are the ones that ran here.