본문으로 건너뛰기
빠른 시작

빠른 시작

첫 요청을 보내 보세요. 키를 받고, 메시지 하나를 보내고, 응답을 읽습니다. API는 OpenAI와 Anthropic 형식을 사용하므로 이미 쓰고 있는 SDK의 기본 URL과 키만 바꾸면 작동합니다.

1. 키 받기

모든 계정에는 API 키가 하나 있습니다. 로그인한 뒤 Keys & usage를 열어 복사하세요. 이 키는 모든 엔드포인트와 모든 모델에서 작동합니다. Keys & usage

2. 클라이언트를 API에 연결

모든 엔드포인트는 하나의 기본 URL 아래에 있습니다. OpenAI SDK에는 끝에 /v1을 붙여서 지정하고, Anthropic SDK는 /v1/messages를 스스로 추가하므로 붙이지 않고 지정합니다.

클라이언트 기본 URL
OpenAI SDK 및 OpenAI 호환 클라이언트 https://api.shannon-ai.com/v1
Anthropic SDK https://api.shannon-ai.com

세 엔드포인트가 텍스트를 생성합니다. 같은 모델에 연결되므로 코드가 이미 사용하는 형식의 엔드포인트를 고르세요.

엔드포인트 형식
POST /v1/chat/completions OpenAI Chat Completions
POST /v1/messages Anthropic Messages
POST /v1/responses OpenAI Responses

3. 첫 요청 보내기

Chat Completions 엔드포인트에서 shannon-3에 user 메시지 하나를 보냅니다. YOUR_API_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)
필드 유형 기본값 설명
model string 응답할 모델의 id입니다. id는 Models & pricing에 나열되어 있습니다.
messages array 지금까지의 대화이며 role과 content가 있는 객체들입니다. 마지막 user 메시지가 프롬프트입니다. 필수입니다.
max_tokens integer 4096 요청의 출력 예산이며 1에서 65,536 사이입니다. 요청은 이 양을 잔액에서 확보하고 실제로 사용한 만큼만 청구됩니다.
stream boolean false true이면 답변이 작성되는 동안 조금씩 나누어 보냅니다.

요청 본문은 JSON이며 Content-Type: application/json 헤더가 필요합니다. 전체 필드 목록은 엔드포인트 페이지에 있습니다. Chat Completions

응답

stream 없이 호출하면 답변이 완료되었을 때 JSON 객체 하나를 반환합니다. 아래의 텍스트와 숫자는 예시입니다.

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
  }
}
필드 유형 설명
id string chatcmpl- 뒤에 hex 문자 32개가 붙습니다.
object string 항상 chat.completion입니다.
created integer 응답 시각이며 Unix 초 단위입니다.
model string 응답한 모델의 공개된 id입니다. 별칭이나 다른 표기로 보냈을 때도 마찬가지입니다.
choices array 항상 index 0인 항목 하나입니다.
choices[0].message.role string 항상 assistant입니다.
choices[0].message.content string | null 답변입니다. 응답에 tool_calls가 있으면 null일 수 있습니다.
choices[0].message.reasoning_content string | null 답변 전에 모델이 한 추론이며, 없으면 null입니다.
choices[0].message.tool_calls array 모델이 선언한 도구 중 하나를 호출할 때만 있습니다.
choices[0].finish_reason string 답변이면 stop, 모델이 도구를 호출하면 tool_calls입니다.
usage.prompt_tokens integer 이 답변을 위해 모델이 읽은 토큰입니다. shannon-2-*와 Shannon 3 계열에서는 보낸 텍스트보다 많을 수 있습니다.
usage.completion_tokens integer 모델이 작성한 토큰입니다.
usage.total_tokens integer 합계입니다. Shannon 모델의 청구액은 이 값으로 계산됩니다.
  • usage에는 금액이 아니라 토큰 수가 들어 있습니다. 호출이 잔액에서 차감한 양은 Keys & usage에서 요청별로 확인할 수 있으며, 계산 방식은 Limits and balance에 있습니다. 한도 및 잔액
  • 오류와 스트림을 포함한 모든 응답에는 x-request-id 헤더가 있습니다. 요청에 x-request-id 헤더가 있으면 그 값이 돌아오고, 없으면 값은 12자리 hex 문자열입니다. 이 요청 하나를 가리키는 값이므로 로그에 남겨 두세요.

같은 호출을 스트림으로

stream을 true로 설정하면 답변이 작성되는 동안 읽을 수 있습니다. 요청의 나머지는 모두 그대로입니다.

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)

스트림의 각 프레임은 data:로 시작하고 JSON 객체를 담은 한 줄입니다. 여러 줄로 출력한 프레임 하나:

프레임 하나
{
  "id": "chatcmpl-9b2f6c1e4a7d4f0f8a3c5d2e1b6a7c90",
  "object": "chat.completion.chunk",
  "created": 1791590400,
  "model": "shannon-3",
  "choices": [
    {
      "index": 0,
      "delta": {
        "content": "Hello! "
      },
      "finish_reason": null
    }
  ]
}
프레임(순서대로) delta finish_reason
모델이 추론하는 동안입니다. 프레임이 없을 수도 있고 여러 개일 수도 있습니다. {"reasoning_content": "…"} null
답변이 조금씩 나옵니다. 프레임이 없을 수도 있고 여러 개일 수도 있습니다. {"content": "…"} null
마지막 JSON 프레임입니다. usage도 담겨 있으며 따로 요청할 필요가 없습니다. {} "stop"
스트림의 끝: data: [DONE] 줄.
  • 응답의 상태는 200이고 content-type: text/event-stream입니다. 모든 프레임은 data: <json> 한 줄 뒤에 빈 줄이 오는 형태입니다.
  • : ping 줄이 15초마다 도착합니다. 연결을 유지하는 주석이며 SSE 클라이언트는 이를 건너뜁니다.
  • 스트림이 열린 뒤의 실패는 data: {"error": {…}} 프레임으로 도착합니다. 상태는 200으로 유지되므로 프레임을 확인하세요.

스트리밍

호출이 실패하면

오류는 type과 message를 담은 error가 있는 JSON 객체입니다. 첫 호출에서 가장 자주 만나는 응답은 다음과 같습니다.

상태 유형 메시지 의미
401 authentication_error Missing authentication API에 키가 도달하지 않았습니다. Authorization: Bearer 뒤에 키를 붙여 보내세요.
401 authentication_error Invalid API key 이 키는 어떤 계정의 현재 키도 아닙니다. Keys & usage에서 다시 복사하세요.
400 invalid_request_error unknown model: <id> model이 공개된 id가 아닙니다. Models & pricing의 id를 사용하세요.
422 invalid_request_error Failed to deserialize the JSON body into the target type… 필드의 JSON 타입이 잘못되었거나 messages가 없습니다.
429 rate_limit_error Quota exceeded. Upgrade your plan at shannon-ai.com/plan 요청의 출력 예산이 잔액에 들어가지 않습니다.

오류 처리

다음 단계

  • 모델 및 가격 — 모델 선택: id, 컨텍스트 윈도우, 가격입니다.
  • Chat Completions — 호출한 엔드포인트의 모든 요청 필드, 응답 필드, 스트림 이벤트입니다.
  • 스트리밍 — 스트림의 프레임, keep-alive 줄, 스트림 안의 오류입니다.
  • 함수 호출 — 모델이 사용자의 함수를 호출하도록 하세요.
  • 한도 및 잔액 — 요청이 확보하는 양과 비용, 그리고 보낼 수 있는 요청 수입니다.
  • API 플레이그라운드 — 브라우저에서 키로 요청을 시험해 보세요.