빠른 시작
첫 요청을 보내 보세요. 키를 받고, 메시지 하나를 보내고, 응답을 읽습니다. 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) import OpenAI from 'openai';
const client = new OpenAI({
apiKey: 'YOUR_API_KEY',
baseURL: 'https://api.shannon-ai.com/v1'
});
const response = await client.chat.completions.create({
model: 'shannon-3',
messages: [
{ role: 'user', content: 'Hello, Shannon!' }
],
max_tokens: 1024
});
console.log(response.choices[0].message.content); package main
import (
"context"
"fmt"
openai "github.com/sashabaranov/go-openai"
)
func main() {
config := openai.DefaultConfig("YOUR_API_KEY")
config.BaseURL = "https://api.shannon-ai.com/v1"
client := openai.NewClientWithConfig(config)
resp, err := client.CreateChatCompletion(
context.Background(),
openai.ChatCompletionRequest{
Model: "shannon-3",
Messages: []openai.ChatCompletionMessage{
{Role: "user", Content: "Hello, Shannon!"},
},
MaxTokens: 1024,
},
)
if err != nil {
panic(err)
}
fmt.Println(resp.Choices[0].Message.Content)
} curl -X POST "https://api.shannon-ai.com/v1/chat/completions" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "shannon-3",
"messages": [
{"role": "user", "content": "Hello, Shannon!"}
],
"max_tokens": 1024
}' | 필드 | 유형 | 기본값 | 설명 |
|---|---|---|---|
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 객체 하나를 반환합니다. 아래의 텍스트와 숫자는 예시입니다.
{
"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) import OpenAI from 'openai';
const client = new OpenAI({
apiKey: 'YOUR_API_KEY',
baseURL: 'https://api.shannon-ai.com/v1'
});
const stream = await client.chat.completions.create({
model: 'shannon-3',
messages: [
{ role: 'user', content: 'Hello, Shannon!' }
],
max_tokens: 1024,
stream: true
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
} curl -N -X POST "https://api.shannon-ai.com/v1/chat/completions" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "shannon-3",
"messages": [
{"role": "user", "content": "Hello, Shannon!"}
],
"max_tokens": 1024,
"stream": 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 플레이그라운드 — 브라우저에서 키로 요청을 시험해 보세요.