> ## Documentation Index
> Fetch the complete documentation index at: https://docs.thesys.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrating C1 in your backend

> Learn how to invoke the C1 API from your backend using OpenAI library

This guide walks you through setting up your client, structuring your API requests, and implementing the most common backend patterns for both conversational and standalone applications.

{/* todo: steps component don't show up in the LHS, need to fix this */}

## Implementation

### 1. Setup and Authentication

C1 API is designed to be fully compatible with the OpenAI Chat Completions API. The recommended way to interact with the endpoint is to use the official OpenAI client library for your preferred language.

To get started, you need to initialize the client with your **Thesys API Key** and the **C1 Base URL**.

<Note>You can create a new API key from [Developer Console](https://console.thesys.dev/keys)</Note>

<CodeGroup dropdown>
  ```python main.py theme={null}
  import os
  from openai import OpenAI

  # Initialize the client with your C1 API Key and the C1 Base URL
  client = OpenAI(
      api_key=os.environ.get("THESYS_API_KEY"),
      base_url="https://api.thesys.dev/v1/embed"
  )
  ```

  ```typescript src/app/api/chat/route.ts theme={null}
  import OpenAI from 'openai';

  // Initialize the client with your C1 API Key and the C1 Base URL
  const client = new OpenAI({
    apiKey: process.env.THESYS_API_KEY,
    baseURL: 'https://api.thesys.dev/v1/embed',
  });
  ```
</CodeGroup>

### 2. Structuring the API Request

The core of every request is the `messages` array, which provides the conversational context to the model.

The array consists of one or more message objects, each with a `role` and `content`:

* `role: 'system'`: Provides high-level instructions or context for the AI. This is typically the first message in the array.
* `role: 'user'`: Represents a prompt or message from the end-user.
* `role: 'assistant'`: Represents a previous response from the AI.

**Conversation history** is managed by including the sequence of past `user` and `assistant` messages in the array before adding the latest user prompt.

```json theme={null}
[
    { "role": "system", "content": "You are a helpful assistant that generates UI." },
    { "role": "user", "content": "Show me last month's sales." },
    { "role": "assistant", "content": "<UI spec for a sales chart...>" },
    { "role": "user", "content": "Now break it down by region." }
]
```

You must also specify the `model` you wish to use. For a full list of available models, see the [Models and Pricing](/api-reference/models-and-compatibility) guide.

### 3. Implementation Patterns

Your implementation will depend on whether you are building a conversational application that needs to remember context or a standalone tool that handles one-off requests.

<Tabs>
  <Tab title="Conversational Application">
    In a conversational pattern, your backend must store and manage the history of the conversation. On each new request, you retrieve the history, add the new user message, and then save the assistant's response to persist the context.

    The following is a simplified but complete example using an in-memory array for history. In a production application, you would replace this with a database.

    <CodeGroup dropdown>
      ```python main.py (FastAPI) theme={null}
      import os
      from openai import OpenAI
      from fastapi import FastAPI
      from pydantic import BaseModel

      # --- Basic Setup ---
      app = FastAPI()
      client = OpenAI(
          api_key=os.environ.get("THESYS_API_KEY"),
          base_url="https://api.thesys.dev/v1/embed"
      )

      # In-memory store for conversation history (for demonstration purposes)
      conversation_history = [
          {"role": "system", "content": "You are a helpful assistant."}
      ]

      class ChatRequest(BaseModel):
          prompt: str

      # --- API Endpoint ---
      @app.post("/chat")
      def chat(request: ChatRequest):
          # 1. Add the new user message to the history
          conversation_history.append({"role": "user", "content": request.prompt})

          # 2. Call the C1 API with the full history
          completion = client.chat.completions.create(
              model="c1-model-name",
              messages=conversation_history,
          )
          assistant_response = completion.choices[0].message

          # 3. Add the AI's response to the history
          conversation_history.append(assistant_response)

          # 4. Return the latest response content to the frontend
          return assistant_response.content
      ```

      ```typescript route.ts (Next.js) theme={null}
      import { NextRequest, NextResponse } from "next/server";
      import OpenAI from 'openai';
      import { ChatCompletionMessageParam } from "openai/resources/index.mjs";

      // --- Basic Setup ---
      const client = new OpenAI({
        apiKey: process.env.THESYS_API_KEY,
        baseURL: 'https://api.thesys.dev/v1/embed',
      });

      // In-memory store for conversation history (for demonstration purposes)
      const conversationHistory: ChatCompletionMessageParam[] = [
          { role: "system", content: "You are a helpful assistant." }
      ];

      // --- API Endpoint ---
      export async function POST(req: NextRequest) {
        const { prompt } = (await req.json()) as { prompt: string };

        // 1. Add the new user message to the history
        conversationHistory.push({ role: "user", content: prompt });

        // 2. Call the C1 API with the full history
        const completion = await client.chat.completions.create({
          model: 'c1-model-name',
          messages: conversationHistory,
        });
        const assistantResponse = completion.choices[0].message;

        // 3. Add the AI's response to the history
        conversationHistory.push(assistantResponse);

        // 4. Return the latest response content to the frontend
        return assistantResponse.content;
      }
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Standalone Request">
    For standalone tools, like generating a dashboard widget from a prompt, you don't need to manage a persistent conversation history. Each request is self-contained.

    The `messages` array is typically simpler, containing just a `system` message for context and the single `user` message.

    <CodeGroup dropdown>
      ```python main.py (FastAPI) theme={null}
      import os
      from openai import OpenAI
      from fastapi import FastAPI
      from pydantic import BaseModel

      app = FastAPI()
      client = OpenAI(
          api_key=os.environ.get("THESYS_API_KEY"),
          base_url="https://api.thesys.dev/v1/embed"
      )

      class GenerationRequest(BaseModel):
          prompt: str

      @app.post("/generate-widget")
      def generate(request: GenerationRequest):
          completion = client.chat.completions.create(
              model="c1-model-name",
              messages=[
                  {"role": "system", "content": "You generate UI widgets for a financial dashboard."},
                  {"role": "user", "content": request.prompt}
              ],
          )
          assistant_response = completion.choices[0].message
          return assistant_response.content
      ```

      ```typescript route.ts (Next.js) theme={null}
      import { NextRequest, NextResponse } from "next/server";
      import OpenAI from 'openai';

      const client = new OpenAI({
        apiKey: process.env.THESYS_API_KEY,
        baseURL: 'https://api.thesys.dev/v1/embed',
      });

      export async function POST(req: NextRequest) {
          const { prompt } = (await req.json()) as { prompt: string };

          const completion = await client.chat.completions.create({
            model: 'c1-model-name',
            messages: [
              { role: "system", content: "You generate UI widgets for a financial dashboard." },
              { role: "user", content: prompt }
            ],
          });
          const assistantResponse = completion.choices[0].message;
          return assistantResponse.content;
      }
      ```
    </CodeGroup>
  </Tab>
</Tabs>

## C1 API Reference

* **Endpoint**: `POST /chat/completions`
* **Authentication**: The API uses `Authorization: Bearer <THESYS_API_KEY>`. The client libraries handle this header for you.

### Supported Parameters

The C1 API supports the following standard OpenAI chat completion parameters:

* `model` (string, required): The model ID to use for the generation.
* `messages` (array, required): A list of message objects that form the conversation history.
* `stream` (boolean, optional): If `true`, the response will be streamed back in chunks.
* `temperature` (number, optional): Controls randomness. Defaults to 1.0.
* `max_tokens` (integer, optional): The maximum number of tokens to generate.
* `top_p` (number, optional): Nucleus sampling parameter.
* `stop` (string or array, optional): Sequences where the API will stop generating further tokens.

### Error Handling

The API returns standard HTTP status codes and an error object compatible with OpenAI's format in case of failure.

````json theme={null}
{
  "error": {
    "message": "Invalid API key provided.",
    "type": "invalid_request_error",
    "param": null,
    "code": "invalid_api_key"
  }
}```
````
