Developer guide

Quickstart

Quickstart

This guide covers everything from issuing a CLEVI API key to sending your first request and receiving a response. One address and one key let you call cip-5.5-im and cip-5.5-mm, and because requests and responses follow the OpenAI Chat Completions format, you only need to change two values in the OpenAI SDK you already use: base_url and api_key. The path for the Anthropic SDK and the embeddings and speech paths are covered in the Make API calls document.

Issuing an API key

Keys are issued on the API Keys page of the CLEVI Cloud console. The same page lets you revoke keys and manage their scope. Follow the steps below to get a key to use in requests.

  1. Sign in or create an account: https://platform.clevi.net/account/login
  2. Add a workspace: https://clevi.app/cloud
  3. Go to https://clevi.app/cloud/keys
  4. Issue a new key and copy its value.
  5. Save the copied value in an environment variable.

Replace sk-... in the examples in this guide with the key you issued. If you store it in an environment variable with the command below, you can copy and run the later examples as they are.

export CLEVI_API_KEY="sk-..."

Choosing a model

Put one of the names below in the model field of the request body exactly as shown. Both models use the same address and the same request format, and accept text and images as input.

  • cip-5.5-im
  • cip-5.5-mm
Model IDSizeInput limitMax outputSuited for
cip-5.5-im360B256K64KTasks with a clear goal and scope. Prioritizes response speed and throughput.
cip-5.5-mm800B512K64KComplex tasks that combine many sources and constraints. Used for long-context analysis and multi-step agents.

The models your account can actually call are determined by the Playground model list and the GET /models response. The full model list and the calls each model allows are in the Models document; estimated credit deductions are on the Usage page of the console.

POST /api/v2/aiservice/openai/v1/chat/completions

Takes an array of messages and a model name and returns the message generated by the model in the choices array. The full address is https://platform.clevi.net/api/v2/aiservice/openai/v1/chat/completions and the request body is application/json. Authentication uses the Authorization header with the Bearer prefix followed by the key. You can also send the key in the X-API-Key header; if both headers are specified, the X-API-Key value takes precedence.

Request parameters
NameTypeRequiredDescription
modelstringYescip-5.5-im or cip-5.5-mm
messagesarrayYesArray of conversation message objects. At least 1
messages[].rolestringYesOne of system, user, or assistant
messages[].contentstringYesMessage body
streambooleanNoIf true, the response is delivered in Server-Sent Events chunks
max_tokensintegerNoMaximum number of tokens to generate in the response
temperaturenumberNoThe higher the value, the more likely the same request produces different responses
curl https://platform.clevi.net/api/v2/aiservice/openai/v1/chat/completions \
  -H "Authorization: Bearer $CLEVI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "cip-5.5-im",
    "messages": [
      {"role": "user", "content": "CLEVI API를 한 문장으로 설명해 줘."}
    ]
  }'
import os
import requests

url = "https://platform.clevi.net/api/v2/aiservice/openai/v1/chat/completions"

response = requests.post(
    url,
    headers={"Authorization": f"Bearer {os.environ['CLEVI_API_KEY']}"},
    json={
        "model": "cip-5.5-im",
        "messages": [{"role": "user", "content": "CLEVI API를 한 문장으로 설명해 줘."}],
    },
    timeout=60,
)

print(response.json()["choices"][0]["message"]["content"])
const url =
  "https://platform.clevi.net/api/v2/aiservice/openai/v1/chat/completions";

const response = await fetch(url, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CLEVI_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "cip-5.5-im",
    messages: [{ role: "user", content: "CLEVI API를 한 문장으로 설명해 줘." }],
  }),
});

const data = await response.json();
console.log(data.choices[0].message.content);

Example response. The id, created, and usage values differ for each request.

{
  "id": "chatcmpl-3f0a9c72",
  "object": "chat.completion",
  "created": 1755500000,
  "model": "cip-5.5-im",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "CLEVI API는 주소 하나로 여러 모델을 호출하는 채팅 완료 API입니다."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 21,
    "completion_tokens": 19,
    "total_tokens": 40
  }
}

Calling with the OpenAI SDK

Change the OpenAI SDK's base_url to https://platform.clevi.net/api/v2/aiservice/openai/v1 and put your CLEVI key in api_key. Leave the rest of the calling code as it is.

# pip install openai
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["CLEVI_API_KEY"],
    base_url="https://platform.clevi.net/api/v2/aiservice/openai/v1",
)

completion = client.chat.completions.create(
    model="cip-5.5-mm",
    messages=[{"role": "user", "content": "CLEVI API를 한 문장으로 설명해 줘."}],
)

print(completion.choices[0].message.content)
// npm install openai
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.CLEVI_API_KEY,
  baseURL: "https://platform.clevi.net/api/v2/aiservice/openai/v1",
});

const completion = await client.chat.completions.create({
  model: "cip-5.5-mm",
  messages: [{ role: "user", content: "CLEVI API를 한 문장으로 설명해 줘." }],
});

console.log(completion.choices[0].message.content);

Receiving a stream

Set stream to true in the request body and the server responds with Server-Sent Events. The first chunk arrives with the Content-Type: text/event-stream, Cache-Control: no-cache, and X-Accel-Buffering: no headers, and each chunk after that carries a chat.completion.chunk object in a data: line. The last line is data: [DONE]. The Python and TypeScript examples below reuse the client created in the previous section.

curl -N https://platform.clevi.net/api/v2/aiservice/openai/v1/chat/completions \
  -H "Authorization: Bearer $CLEVI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "cip-5.5-im",
    "messages": [{"role": "user", "content": "CLEVI API를 한 문장으로 설명해 줘."}],
    "stream": true
  }'
stream = client.chat.completions.create(
    model="cip-5.5-im",
    messages=[{"role": "user", "content": "CLEVI API를 한 문장으로 설명해 줘."}],
    stream=True,
)

for chunk in stream:
    delta = chunk.choices[0].delta.content
    if delta:
        print(delta, end="")
const stream = await client.chat.completions.create({
  model: "cip-5.5-im",
  messages: [{ role: "user", content: "CLEVI API를 한 문장으로 설명해 줘." }],
  stream: true,
});

for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}

Example chunks.

data: {"id":"chatcmpl-3f0a9c72","object":"chat.completion.chunk","model":"cip-5.5-im","choices":[{"index":0,"delta":{"content":"CLEVI"},"finish_reason":null}]}

data: {"id":"chatcmpl-3f0a9c72","object":"chat.completion.chunk","model":"cip-5.5-im","choices":[{"index":0,"delta":{"content":" API는"},"finish_reason":null}]}

data: {"id":"chatcmpl-3f0a9c72","object":"chat.completion.chunk","model":"cip-5.5-im","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: [DONE]

If an error occurs during streaming, the same error JSON arrives as a single data: line, and the HTTP status code changes with it.

Errors

A failed request reports its cause with an HTTP status code. If the upstream returns a 4xx or 5xx, that code is passed through as is. Check the actions in the table below first, and if the same code repeats, keep the request time, the body you sent, and the X-Request-Id.

HTTP status codes
CodeMeaningWhat to do
400The request body is malformedCheck that model and messages are present and that the JSON is closed
401The key is missing, expired, or revokedCheck the key status on the API Keys page and confirm that the Authorization header starts with Bearer
403No access to the model, usage limit exceeded, or insufficient creditsCheck error.message for the reason. Limits are under Allocated usage limits on the Overview page; balance and plan are under Plan and credits
404The model does not exist or is not accessible with this key, or the path does not existCheck that the model name appears in the GET /models response and that the address ends with /api/v2/aiservice/openai/v1/chat/completions
429The upstream provider applied a rate limitIf a Retry-After header is present, wait that long; otherwise double the retry interval each time and resend
5xxA temporary error in the gateway or upstreamResend with a retry interval that doubles each time, and if it repeats, report it through Help and Support with the X-Request-Id

402 is never returned. Insufficient credits and exceeded usage limits come back as 403. The error body has the format below, with the reason in error.message.

{"error":{"message":"API key is required.","type":"invalid_request_error"}}

If you include an X-Request-Id header in the request, that value is used to trace it when you contact support. If you do not send one, the server issues it.

Next steps

Comparing results across model names and parameters is done in the Playground. Creating or revoking keys is done on the API Keys page. Documents to read next:

  • Models: the full model list, per-model specifications, and allowed calls
  • Make API calls: the Anthropic-compatible path, embeddings and speech paths, and streaming rules
  • Error codes: the full status code table and retry rules

Open the Playground

Manage API keys

Language and region

Machine-translated languages are translated by clevi/cip-5.5-im and marked as such. This applies to languages with a published site bundle.

137 languages

Recommended

1

East Asia

7

Southeast Asia

11

South Asia

18

Central Asia

5

Middle East and the Caucasus

10

Western and Southern Europe

17

Britain and Ireland

4

Northern Europe and the Baltics

10

Central Europe and the Balkans

14

Eastern Europe

5

East Africa and the Horn

8

West and Central Africa

9

Southern Africa

8

The Americas

5

The Pacific

5