Skip to content
Quick Start

Quick Start

Make a first request: get your key, send one message and read the reply. The API speaks the OpenAI and Anthropic formats, so the SDK you already use works after you change its base URL and key.

1. Get your key

Every account has one API key. Sign in, open Keys & usage and copy it. The key works on every endpoint and every model. Keys & usage

2. Point your client at the API

All endpoints live under one base URL. An OpenAI SDK takes it with /v1 at the end; an Anthropic SDK takes it without, because it adds /v1/messages itself.

Client Base URL
OpenAI SDKs and OpenAI-compatible clients https://api.shannon-ai.com/v1
Anthropic SDKs https://api.shannon-ai.com

Three endpoints produce text. They reach the same models; choose the one whose format your code already uses.

Endpoint Format
POST /v1/chat/completions OpenAI Chat Completions
POST /v1/messages Anthropic Messages
POST /v1/responses OpenAI Responses

3. Send a first request

Send one user message to shannon-3 on the Chat Completions endpoint. Replace YOUR_API_KEY with your key.

POST https://api.shannon-ai.com/v1/chat/completions

from openai import OpenAI

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.shannon-ai.com/v1"
)

response = client.chat.completions.create(
    model="shannon-3",
    messages=[
        {"role": "user", "content": "Hello, Shannon!"}
    ],
    max_tokens=1024
)

print(response.choices[0].message.content)
Field Type Default Description
model string The id of the model that answers. The ids are listed on Models & pricing.
messages array The conversation so far: objects with role and content. The last user message is the prompt. Required.
max_tokens integer 4096 The output budget of the request, from 1 to 65,536. The request reserves this amount from your balance and is charged for what it really used.
stream boolean false true sends the answer piece by piece while it is written.

The request body is JSON and needs the header Content-Type: application/json. The full list of fields is on the endpoint page. Chat Completions

The reply

A call without stream returns one JSON object when the answer is complete. The texts and numbers below are examples.

200 JSON
{
  "id": "chatcmpl-9b2f6c1e4a7d4f0f8a3c5d2e1b6a7c90",
  "object": "chat.completion",
  "created": 1791590400,
  "model": "shannon-3",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Hello! What would you like to work on?",
        "reasoning_content": "A greeting. A short, friendly reply fits."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 1386,
    "completion_tokens": 74,
    "total_tokens": 1460
  }
}
Field Type Description
id string chatcmpl- followed by 32 hexadecimal characters.
object string Always chat.completion.
created integer The time of the reply in Unix seconds.
model string The published id of the model that answered, also when you sent an alias or another spelling.
choices array Always one entry, with index 0.
choices[0].message.role string Always assistant.
choices[0].message.content string | null The answer. It can be null when the reply carries tool_calls.
choices[0].message.reasoning_content string | null The reasoning of the model before its answer, or null when there is none.
choices[0].message.tool_calls array Present only when the model calls one of the tools you declared.
choices[0].finish_reason string stop for an answer, tool_calls when the model calls a tool.
usage.prompt_tokens integer The tokens the model read for this answer. On shannon-2-* and the Shannon 3 family this can be more than the text you sent.
usage.completion_tokens integer The tokens the model wrote.
usage.total_tokens integer The total. The charge of a Shannon model is computed from this number.
  • usage holds token counts, not money. What the call took from your balance is shown per request on Keys & usage; how it is computed is on Limits and balance. Limits and balance
  • Every reply, also an error and a stream, has the header x-request-id. If your request carries an x-request-id header, its value comes back; otherwise the value is 12 hexadecimal characters. Keep it in your logs: it names this one request.

The same call as a stream

Set stream to true to read the answer while it is written. Everything else in the request stays the same.

from openai import OpenAI

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.shannon-ai.com/v1"
)

stream = client.chat.completions.create(
    model="shannon-3",
    messages=[
        {"role": "user", "content": "Hello, Shannon!"}
    ],
    max_tokens=1024,
    stream=True
)

for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

Each frame of the stream is one line that starts with data: and holds a JSON object. One frame, printed on several lines:

One frame
{
  "id": "chatcmpl-9b2f6c1e4a7d4f0f8a3c5d2e1b6a7c90",
  "object": "chat.completion.chunk",
  "created": 1791590400,
  "model": "shannon-3",
  "choices": [
    {
      "index": 0,
      "delta": {
        "content": "Hello! "
      },
      "finish_reason": null
    }
  ]
}
Frames, in order delta finish_reason
While the model reasons. Zero or more frames. {"reasoning_content": "…"} null
The answer, piece by piece. Zero or more frames. {"content": "…"} null
The last JSON frame. It also carries usage; you do not have to ask for it. {} "stop"
The end of the stream: the line data: [DONE].
  • The reply has status 200 and content-type: text/event-stream. Every frame is a line data: <json> followed by an empty line.
  • A line : ping arrives every 15 seconds. It is a comment that keeps the connection open; SSE clients skip it.
  • A failure after the stream has opened arrives as a frame data: {"error": {…}}. The status stays 200, so check the frames.

Streaming

If the call fails

An error is a JSON object with an error that holds type and message. These are the replies a first call most often meets.

Status Type Message What it means
401 authentication_error Missing authentication No key reached the API. Send Authorization: Bearer followed by your key.
401 authentication_error Invalid API key The key is not the current key of an account. Copy it again from Keys & usage.
400 invalid_request_error unknown model: <id> model is not a published id. Use an id from Models & pricing.
422 invalid_request_error Failed to deserialize the JSON body into the target type… A field has the wrong JSON type, or messages is missing.
429 rate_limit_error Quota exceeded. Upgrade your plan at shannon-ai.com/plan The output budget of the request does not fit into your balance.

Error Handling

Where to go next

  • Models & pricing — Pick a model: ids, context windows and prices.
  • Chat Completions — Every request field, reply field and stream event of the endpoint you called.
  • Streaming — The frames of a stream, keep-alive lines and errors inside a stream.
  • Function Calling — Let the model call your functions.
  • Limits and balance — What a request reserves and costs, and how many requests you may send.
  • API Playground — Try requests in the browser with your key.