# API Quickstart & Advanced Examples

We don’t ship an official SDK. Call us over plain HTTP/HTTPS using the OpenAI-style protocol.

If you already use OpenAI’s official/community SDKs, you can usually just point base\_url to our gateway and swap the api\_key to your Console key. *(Those SDKs aren’t maintained by us.)*

### 1) Setup

* Base URL: https\://\<your-gateway>/v1
* API Key: Create in the Console; send via header Authorization: Bearer \<key>
* model: e.g., gpt-4.1-mini, gpt-4o, DeepSeek-V3 (see Model Catalog & Pricing)

```bash
export SIGHT_API_BASE="https://<your-gateway>/v1"
export SIGHT_API_KEY="sk-************************"
```

***

### 2) Minimal HTTP Examplesbash

#### 2.1 cURL

```bash
curl -X POST "$SIGHT_API_BASE/chat/completions" \
  -H "Authorization: Bearer $SIGHT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4.1-mini",
    "messages": [{"role":"user","content":"Hello, SightAI!"}]
  }'
```

#### 2.2 Node.js (native fetch, Node 18+)

```javascript
const res = await fetch(`${process.env.SIGHT_API_BASE}/chat/completions`, {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SIGHT_API_KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    model: "gpt-4.1-mini",
    messages: [{ role: "user", content: "Hello" }]
  })
});
const data = await res.json();
console.log(data.choices?.[0]?.message?.content);
```

#### 2.3 Python (requests)

```python
import os, requests
r = requests.post(
  f"{os.environ['SIGHT_API_BASE']}/chat/completions",
  headers={
    "Authorization": f"Bearer {os.environ['SIGHT_API_KEY']}",
    "Content-Type": "application/json"
  },
  json={
    "model":"gpt-4.1-mini",
    "messages":[{"role":"user","content":"Hello"}]
  },
  timeout=60
)
print(r.status_code, r.json()["choices"][0]["message"]["content"])
```

***

### 3) Streaming (SSE)

3.1 Node.js (manual SSE parsing)

```javascript
const res = await fetch(`${process.env.SIGHT_API_BASE}/chat/completions`, {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SIGHT_API_KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    model: "gpt-4.1-mini",
    stream: true,
    messages: [{ role: "user", content: "Say hi in 3 words." }]
  })
});

const reader = res.body.getReader();
const decoder = new TextDecoder();
let buffer = "";

while (true) {
  const { value, done } = await reader.read();
  if (done) break;
  buffer += decoder.decode(value, { stream: true });
  const lines = buffer.split("\n");
  buffer = lines.pop() || "";
  for (const line of lines) {
    if (!line.startsWith("data: ")) continue;
    const payload = line.slice(6).trim();
    if (!payload || payload === "[DONE]") continue;
    const json = JSON.parse(payload);
    const piece = json.choices?.[0]?.delta?.content || "";
    if (piece) process.stdout.write(piece);
  }
}
```

#### 3.2 Python (requests stream)

```python
import os, requests, json
resp = requests.post(
  f"{os.environ['SIGHT_API_BASE']}/chat/completions",
  headers={
    "Authorization": f"Bearer {os.environ['SIGHT_API_KEY']}",
    "Content-Type": "application/json"
  },
  json={
    "model":"gpt-4.1-mini",
    "stream": True,
    "messages":[{"role":"user","content":"Say hi in 3 words."}]
  },
  stream=True, timeout=300
)
for line in resp.iter_lines():
  if not line: 
    continue
  if line.startswith(b"data: "):
    payload = line[6:].strip()
    if payload == b"[DONE]":
      break
    chunk = json.loads(payload)
    piece = chunk.get("choices",[{}])[0].get("delta",{}).get("content","")
    if piece:
      print(piece, end="", flush=True)
```

***

### 4) Function / Tool Calls (OpenAI style)

The model proposes a tool name and arguments (per your declared schema). You execute it locally and append the tool result back into the conversation.

\
Node.js (HTTP version)

```javascript
async function getPrice({ symbol }) {
  return { symbol, price: 1.23, currency: "USD", ts: Date.now() };
}

const tools = [{
  type: "function",
  function: {
    name: "getPrice",
    description: "Get the latest token price (demo)",
    parameters: {
      type: "object",
      properties: {
        symbol: { type: "string", description: "Token symbol, e.g., BTC/ETH" }
      },
      required: ["symbol"]
    }
  }
}];

let messages = [{ role: "user", content: "How much is ETH now?" }];

// Step 1: Let the model decide whether to call a tool
const step1 = await fetch(`${process.env.SIGHT_API_BASE}/chat/completions`, {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SIGHT_API_KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ model: "gpt-4.1-mini", messages, tools })
}).then(r => r.json());

const calls = step1.choices?.[0]?.message?.tool_calls || [];
if (calls.length) {
  // Push the model message containing tool_calls into the thread
  messages.push(step1.choices[0].message);

  for (const c of calls) {
    const args = JSON.parse(c.function.arguments || "{}");
    const result = (c.function.name === "getPrice")
      ? await getPrice(args)
      : { error: "unknown tool" };

    // Step 2: Append tool result
    messages.push({ role: "tool", tool_call_id: c.id, content: JSON.stringify(result) });
  }

  // Step 3: Ask the model for the final answer
  const final = await fetch(`${process.env.SIGHT_API_BASE}/chat/completions`, {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.SIGHT_API_KEY}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ model: "gpt-4.1-mini", messages })
  }).then(r => r.json());

  console.log(final.choices?.[0]?.message?.content);
}
```

***

### 5) Structured Output (JSON):&#x20;

### json\_schema vs  json\_object

Ask the model to return JSON only, so downstream systems can parse it.

* Strict structure — response\_format: { type: "json\_schema" }
  * Natively supported by “OpenAI family” models.
  * Ensures the output strictly conforms to your JSON Schema.
  * Avoid combining with streaming (or validate after the full response).
* Loose structure — response\_format: { type: "json\_object" }
  * Many models (e.g., DeepSeek family) guarantee “JSON” but not perfect schema compliance.
  * Validate with jsonschema/ajv client-side; repair/retry as needed.

\
Strict example (Node.js)

```javascript
const schema = {
  "$schema":"http://json-schema.org/draft-07/schema#",
  "type":"object",
  "required":["name","age","tags"],
  "properties":{
    "name":{"type":"string"},
    "age":{"type":"integer","minimum":0,"maximum":120},
    "tags":{"type":"array","items":{"type":"string"},"maxItems":5}
  },
  "additionalProperties":false
};

const resp = await fetch(`${process.env.SIGHT_API_BASE}/chat/completions`, {
  method:"POST",
  headers:{
    "Authorization":`Bearer ${process.env.SIGHT_API_KEY}`,
    "Content-Type":"application/json"
  },
  body: JSON.stringify({
    model: "gpt-4.1-mini",
    messages: [
      { role:"system", content:"Return JSON only. No explanations." },
      { role:"user", content:"Extract: Alice, 28; hobbies: reading, hiking." }
    ],
    response_format: {
      type:"json_schema",
      json_schema:{ name:"UserProfile", schema, strict:true }
    }
  })
}).then(r => r.json());
console.log(resp.choices?.[0]?.message?.content);
```

#### Loose example (Node.js)

```javascript
import Ajv from "ajv";
const ajv = new Ajv({ allErrors:true, strict:false });

const r = await fetch(`${process.env.SIGHT_API_BASE}/chat/completions`, {
  method:"POST",
  headers:{
    "Authorization":`Bearer ${process.env.SIGHT_API_KEY}`,
    "Content-Type":"application/json"
  },
  body: JSON.stringify({
    model:"DeepSeek-V3",
    messages:[{ role:"user", content:"Return JSON with fields: name/age/tags" }],
    response_format:{ type:"json_object" }
  })
}).then(r => r.json());

const obj = JSON.parse(r.choices[0].message.content);
const validate = ajv.compile({
  "$schema":"http://json-schema.org/draft-07/schema#",
  "type":"object",
  "required":["name","age","tags"],
  "properties":{
    "name":{"type":"string"},
    "age":{"type":"integer","minimum":0,"maximum":120},
    "tags":{"type":"array","items":{"type":"string"}}
  },
  "additionalProperties":false
});
if (!validate(obj)) {
  // local fix / retry / throw
}
```

***

### 6) Errors & Retries&#x20;

* 401: Check Authorization: Bearer \<key>.
* 404: Ensure the path includes /v1.
* 415: Set Content-Type: application/json.
* 429 / rate limit: Use exponential backoff (0.5s → 1s → 2s → 4s; up to 5 tries). Control concurrency and queueing.
* 5xx / timeout: Retry; the platform autocommits fallback to available routes.
* Tracing: Set a custom X-Request-ID to align with Console logs.

***

### 7) Security & Go-Live Tips

* Do not expose your API key in the browser; route calls from your backend.
* Configure timeouts, retries, and concurrency limits to avoid cost spikes and 429s.
* When you need structured output, prefer models with native json\_schema; otherwise use json\_object + client-side validation.
