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

# 4MINDS OpenAI-Compatible API Reference

> Complete reference for 4MINDS OpenAI-compatible REST API endpoints.

> **Note:** This API is OpenAI-compatible. You can use the official OpenAI SDK (Python or JavaScript) by pointing `base_url` / `baseURL` to `https://api.4minds.ai/v1` and providing your 4MINDS API key.

***

## Base URL

```text theme={null}
https://api.4minds.ai
```

***

## Models

OpenAI-compatible models API. List, retrieve, and delete your fine-tuned models.

### List All Available Models

**GET** `/v1/models`

List all available models (OpenAI-compatible).

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET https://api.4minds.ai/v1/models \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```python Python (openai) theme={null}
  from openai import OpenAI

  client = OpenAI(
      api_key="YOUR_API_KEY",
      base_url="https://api.4minds.ai/v1"
  )

  # List all models
  models = client.models.list()

  for model in models.data:
      print(f"Model: {model.id}")
      print(f"  Owner: {model.owned_by}")
      print(f"  Created: {model.created}")
  ```

  ```python Python (requests) theme={null}
  import requests

  url = "https://api.4minds.ai/v1/models"
  headers = {
      "Authorization": "Bearer YOUR_API_KEY"
  }

  response = requests.get(url, headers=headers)
  result = response.json()

  for model in result['data']:
      print(f"Model: {model['id']}")
      print(f"  Owner: {model['owned_by']}")
  ```

  ```javascript JavaScript theme={null}
  import OpenAI from 'openai';

  const openai = new OpenAI({
    apiKey: 'YOUR_API_KEY',
    baseURL: 'https://api.4minds.ai/v1'
  });

  async function listModels() {
    const models = await openai.models.list();

    for (const model of models.data) {
      console.log(`Model: ${model.id}`);
      console.log(`  Owner: ${model.owned_by}`);
    }
  }

  listModels();
  ```

  ```javascript Node.js theme={null}
  const OpenAI = require('openai');

  const openai = new OpenAI({
    apiKey: 'YOUR_API_KEY',
    baseURL: 'https://api.4minds.ai/v1'
  });

  async function listModels() {
    const models = await openai.models.list();

    for (const model of models.data) {
      console.log(`Model: ${model.id}`);
      console.log(`  Owner: ${model.owned_by}`);
    }
  }

  listModels();
  ```
</CodeGroup>

***

### Get Model Details

**GET** `/v1/models/{model_id}`

Get details about a specific model (OpenAI-compatible).

#### Parameters

| Parameter | Type   | Required | Description                        |
| --------- | ------ | -------- | ---------------------------------- |
| model\_id | string | Yes      | The unique identifier of the model |

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET https://api.4minds.ai/v1/models/{model_id} \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```python Python (openai) theme={null}
  from openai import OpenAI

  client = OpenAI(
      api_key="YOUR_API_KEY",
      base_url="https://api.4minds.ai/v1"
  )

  model = client.models.retrieve("your-model-id")
  print(f"Model: {model.id}")
  print(f"Owner: {model.owned_by}")
  ```

  ```javascript JavaScript theme={null}
  import OpenAI from 'openai';

  const openai = new OpenAI({
    apiKey: 'YOUR_API_KEY',
    baseURL: 'https://api.4minds.ai/v1'
  });

  const model = await openai.models.retrieve('your-model-id');
  console.log(`Model: ${model.id}`);
  console.log(`Owner: ${model.owned_by}`);
  ```
</CodeGroup>

***

### Delete a Model

**DELETE** `/v1/models/{model_id}`

Delete a fine-tuned model (OpenAI-compatible).

#### Parameters

| Parameter | Type   | Required | Description                                  |
| --------- | ------ | -------- | -------------------------------------------- |
| model\_id | string | Yes      | The unique identifier of the model to delete |

<CodeGroup>
  ```bash cURL theme={null}
  curl -X DELETE https://api.4minds.ai/v1/models/{model_id} \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```python Python (openai) theme={null}
  from openai import OpenAI

  client = OpenAI(
      api_key="YOUR_API_KEY",
      base_url="https://api.4minds.ai/v1"
  )

  client.models.delete("your-model-id")
  print("Model deleted successfully")
  ```

  ```javascript JavaScript theme={null}
  import OpenAI from 'openai';

  const openai = new OpenAI({
    apiKey: 'YOUR_API_KEY',
    baseURL: 'https://api.4minds.ai/v1'
  });

  await openai.models.delete('your-model-id');
  console.log('Model deleted successfully');
  ```
</CodeGroup>

***

## Chat Completions

OpenAI-compatible chat completions with 4minds Constellations extensions. Supports streaming, agent status events, multi-hop planning, and RAG context retrieval. Stored completions can be listed, retrieved, updated, and deleted.

### Create a Chat Completion

**POST** `/v1/chat/completions`

Create a chat completion (OpenAI-compatible with 4minds extensions).

<CodeGroup>
  ```bash cURL (Basic) theme={null}
  curl -X POST https://api.4minds.ai/v1/chat/completions \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "4minds-model-123",
      "messages": [
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What is machine learning?"}
      ],
      "temperature": 0.7,
      "max_tokens": 500
    }'
  ```

  ```bash cURL (Streaming) theme={null}
  curl -X POST https://api.4minds.ai/v1/chat/completions \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "4minds-model-123",
      "messages": [
        {"role": "user", "content": "Explain neural networks"}
      ],
      "stream": true
    }'
  ```

  ```python Python theme={null}
  from openai import OpenAI

  client = OpenAI(
      api_key="YOUR_API_KEY",
      base_url="https://api.4minds.ai/v1"
  )

  # Basic chat completion
  response = client.chat.completions.create(
      model="4minds-model-123",
      messages=[
          {"role": "system", "content": "You are a helpful assistant."},
          {"role": "user", "content": "What is machine learning?"}
      ],
      temperature=0.7,
      max_tokens=500
  )

  print(response.choices[0].message.content)
  ```

  ```python Python (Streaming) theme={null}
  from openai import OpenAI

  client = OpenAI(
      api_key="YOUR_API_KEY",
      base_url="https://api.4minds.ai/v1"
  )

  # Streaming chat completion
  stream = client.chat.completions.create(
      model="4minds-model-123",
      messages=[
          {"role": "user", "content": "Explain neural networks"}
      ],
      stream=True
  )

  for chunk in stream:
      if chunk.choices[0].delta.content:
          print(chunk.choices[0].delta.content, end="", flush=True)
  ```

  ```javascript JavaScript theme={null}
  import OpenAI from 'openai';

  const openai = new OpenAI({
    apiKey: 'YOUR_API_KEY',
    baseURL: 'https://api.4minds.ai/v1'
  });

  async function chat() {
    const response = await openai.chat.completions.create({
      model: '4minds-model-123',
      messages: [
        { role: 'system', content: 'You are a helpful assistant.' },
        { role: 'user', content: 'What is machine learning?' }
      ],
      temperature: 0.7,
      max_tokens: 500
    });

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

  chat();
  ```

  ```javascript Node.js theme={null}
  const OpenAI = require('openai');

  const openai = new OpenAI({
    apiKey: 'YOUR_API_KEY',
    baseURL: 'https://api.4minds.ai/v1'
  });

  async function chat() {
    const response = await openai.chat.completions.create({
      model: '4minds-model-123',
      messages: [
        { role: 'system', content: 'You are a helpful assistant.' },
        { role: 'user', content: 'What is machine learning?' }
      ],
      temperature: 0.7,
      max_tokens: 500
    });

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

  chat();
  ```
</CodeGroup>

***

### List Stored Chat Completions

**GET** `/v1/chat/completions`

List stored chat completions with optional filtering by model.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.4minds.ai/v1/chat/completions?model=4minds-model-123" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```
</CodeGroup>

***

### Get a Stored Chat Completion

**GET** `/v1/chat/completions/{completion_id}`

Retrieve a stored chat completion by ID.

#### Path Parameters

| Parameter      | Type   | Required | Description                                    |
| -------------- | ------ | -------- | ---------------------------------------------- |
| completion\_id | string | Yes      | The unique identifier of the stored completion |

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET https://api.4minds.ai/v1/chat/completions/{completion_id} \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```
</CodeGroup>

***

### Update a Stored Chat Completion

**POST** `/v1/chat/completions/{completion_id}`

Update a stored chat completion (e.g. rename or set metadata).

#### Path Parameters

| Parameter      | Type   | Required | Description                                    |
| -------------- | ------ | -------- | ---------------------------------------------- |
| completion\_id | string | Yes      | The unique identifier of the stored completion |

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.4minds.ai/v1/chat/completions/{completion_id} \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"title": "Updated Title"}'
  ```
</CodeGroup>

***

### Delete a Stored Chat Completion

**DELETE** `/v1/chat/completions/{completion_id}`

Delete a stored chat completion.

#### Path Parameters

| Parameter      | Type   | Required | Description                                    |
| -------------- | ------ | -------- | ---------------------------------------------- |
| completion\_id | string | Yes      | The unique identifier of the stored completion |

<CodeGroup>
  ```bash cURL theme={null}
  curl -X DELETE https://api.4minds.ai/v1/chat/completions/{completion_id} \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```
</CodeGroup>

***

### List Messages from a Stored Chat Completion

**GET** `/v1/chat/completions/{completion_id}/messages`

List messages from a stored chat completion.

#### Path Parameters

| Parameter      | Type   | Required | Description                                    |
| -------------- | ------ | -------- | ---------------------------------------------- |
| completion\_id | string | Yes      | The unique identifier of the stored completion |

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET https://api.4minds.ai/v1/chat/completions/{completion_id}/messages \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```
</CodeGroup>

***

## Files

OpenAI-compatible file management API. Upload, list, retrieve, and delete files for fine-tuning. 4minds extends OpenAI's single-file upload with multi-file datasets — upload multiple files to a single dataset for training.

### Upload a File

**POST** `/v1/files`

Upload a file for fine-tuning (OpenAI-compatible with multi-file extension).

The response includes a `dataset_id` — use it to upload more files to the same dataset.

**Optional `4minds` form field (JSON string):**

| Field          | Type    | Description                                             |
| -------------- | ------- | ------------------------------------------------------- |
| dataset\_name  | string  | Custom name for the new dataset                         |
| dataset\_id    | integer | Upload to an existing dataset                           |
| training\_type | string  | `"graph"` (default), `"rl"`, or `"sft"`                 |
| model\_params  | object  | Custom hyperparameters, e.g. `{"learning_rate": 0.001}` |

**Behavior:**

| Scenario                      | Result                               |
| ----------------------------- | ------------------------------------ |
| Omit `4minds` entirely        | New dataset with auto-generated name |
| `dataset_name` only           | New dataset with your custom name    |
| `dataset_id` only             | Upload to existing dataset           |
| `dataset_id` + `dataset_name` | `dataset_id` takes priority          |

> **Note:** If the dataset already has a model, training is triggered automatically on upload.

<CodeGroup>
  ```bash cURL theme={null}
  # Standard OpenAI file upload
  curl -X POST https://api.4minds.ai/v1/files \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -F "file=@training_data.jsonl" \
    -F "purpose=fine-tune"

  # With optional 4minds extensions (omit for standard OpenAI behavior)
  curl -X POST https://api.4minds.ai/v1/files \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -F "file=@training_data.jsonl" \
    -F "purpose=fine-tune" \
    -F '4minds={"dataset_name": "My Training Data", "training_type": "graph"}'
  ```

  ```bash cURL (Multi-File Upload) theme={null}
  # Upload multiple files to the SAME dataset

  # Step 1: Upload first file — creates a new dataset
  curl -X POST https://api.4minds.ai/v1/files \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -F "file=@document1.pdf" \
    -F "purpose=fine-tune" \
    -F '4minds={"dataset_name": "My Training Data"}'
  # Response: {"id": "file-abc123...", "dataset_id": 1234, ...}

  # Step 2: Upload more files to the SAME dataset using dataset_id
  curl -X POST https://api.4minds.ai/v1/files \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -F "file=@document2.pdf" \
    -F "purpose=fine-tune" \
    -F '4minds={"dataset_id": 1234}'

  # Step 3: Upload with custom training type and hyperparameters
  curl -X POST https://api.4minds.ai/v1/files \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -F "file=@document3.pdf" \
    -F "purpose=fine-tune" \
    -F '4minds={"dataset_id": 1234, "training_type": "sft", "model_params": {"learning_rate": 0.001}}'

  # Step 4: Create a fine-tuning job using any file from the dataset
  # Training processes ALL files in the dataset
  curl -X POST https://api.4minds.ai/v1/fine_tuning/jobs \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "Gemma-12B AWQ",
      "training_file": "file-abc123...",
      "suffix": "my-custom-model"
    }'
  ```

  ```python Python theme={null}
  from openai import OpenAI

  client = OpenAI(
      api_key="YOUR_API_KEY",
      base_url="https://api.4minds.ai/v1"
  )

  # Standard OpenAI file upload
  with open("training_data.jsonl", "rb") as f:
      file = client.files.create(
          file=f,
          purpose="fine-tune"
      )

  print(f"File ID: {file.id}")
  print(f"Filename: {file.filename}")
  print(f"Size: {file.bytes} bytes")

  # The response includes dataset_id — use it to upload
  # more files to the same dataset via the requests library.
  #
  # Optional '4minds' parameter fields:
  #   dataset_name  (str)  - Custom name for the new dataset
  #   dataset_id    (int)  - Upload to an existing dataset
  #   training_type (str)  - "graph" (default), "rl", or "sft"
  #   model_params  (dict) - e.g. {"learning_rate": 0.001}
  ```

  ```python Python (Multi-File Upload) theme={null}
  import requests
  import json

  api_key = "YOUR_API_KEY"
  base_url = "https://api.4minds.ai/v1/files"
  headers = {"Authorization": f"Bearer {api_key}"}

  # Step 1: Upload first file with a custom dataset name
  with open("document1.pdf", "rb") as f:
      response = requests.post(
          base_url,
          headers=headers,
          files={"file": f},
          data={
              "purpose": "fine-tune",
              "4minds": json.dumps({
                  "dataset_name": "Medical Research Data",
                  "training_type": "graph"
              })
          }
      )

  result = response.json()
  dataset_id = result["dataset_id"]
  print(f"Dataset created: {dataset_id}")
  print(f"File ID: {result['id']}")
  print(f"Status: {result['status']}")

  # Step 2: Upload more files to the SAME dataset
  for filename in ["document2.pdf", "document3.pdf"]:
      with open(filename, "rb") as f:
          response = requests.post(
              base_url,
              headers=headers,
              files={"file": f},
              data={
                  "purpose": "fine-tune",
                  "4minds": json.dumps({"dataset_id": dataset_id})
              }
          )
      print(f"Uploaded {filename}: {response.json()['id']}")

  # Step 3: Create a fine-tuning job — trains ALL files in dataset
  from openai import OpenAI
  client = OpenAI(api_key=api_key, base_url="https://api.4minds.ai/v1")
  job = client.fine_tuning.jobs.create(
      model="Gemma-12B AWQ",
      training_file=result["id"],
      suffix="my-custom-model"
  )
  print(f"Fine-tuning job: {job.id}, Status: {job.status}")
  ```

  ```javascript JavaScript theme={null}
  import OpenAI from 'openai';
  import fs from 'fs';

  const openai = new OpenAI({
    apiKey: 'YOUR_API_KEY',
    baseURL: 'https://api.4minds.ai/v1'
  });

  // Standard OpenAI file upload
  const file = await openai.files.create({
    file: fs.createReadStream('training_data.jsonl'),
    purpose: 'fine-tune'
  });

  console.log(`File ID: ${file.id}`);
  console.log(`Filename: ${file.filename}`);
  console.log(`Size: ${file.bytes} bytes`);

  // The response includes dataset_id — use it to upload
  // more files to the same dataset via fetch().
  //
  // Optional '4minds' form field (JSON string):
  //   dataset_name  (string) - Custom name for the new dataset
  //   dataset_id    (integer) - Upload to an existing dataset
  //   training_type (string) - "graph" (default), "rl", or "sft"
  //   model_params  (object) - e.g. {learning_rate: 0.001}
  ```

  ```javascript JavaScript (Multi-File Upload) theme={null}
  // Upload multiple files to one dataset
  const apiKey = 'YOUR_API_KEY';
  const baseUrl = 'https://api.4minds.ai/v1/files';

  // Step 1: Upload first file with a custom dataset name
  const formData1 = new FormData();
  formData1.append('file', fileInput.files[0]);
  formData1.append('purpose', 'fine-tune');
  formData1.append('4minds', JSON.stringify({
    dataset_name: 'My Training Data',
    training_type: 'graph'
  }));

  const response1 = await fetch(baseUrl, {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${apiKey}` },
    body: formData1
  });

  const result1 = await response1.json();
  const datasetId = result1.dataset_id;
  console.log(`Dataset created: ${datasetId}`);
  console.log(`Status: ${result1.status}`);

  // Step 2: Upload more files to the SAME dataset
  for (const file of additionalFiles) {
    const formData = new FormData();
    formData.append('file', file);
    formData.append('purpose', 'fine-tune');
    formData.append('4minds', JSON.stringify({
      dataset_id: datasetId
    }));

    const response = await fetch(baseUrl, {
      method: 'POST',
      headers: { 'Authorization': `Bearer ${apiKey}` },
      body: formData
    });

    const result = await response.json();
    console.log(`Uploaded ${result.id} (status: ${result.status})`);
  }
  ```

  ```javascript Node.js theme={null}
  const OpenAI = require('openai');
  const fs = require('fs');

  const openai = new OpenAI({
    apiKey: 'YOUR_API_KEY',
    baseURL: 'https://api.4minds.ai/v1'
  });

  async function uploadFile() {
    // Standard OpenAI file upload
    const file = await openai.files.create({
      file: fs.createReadStream('training_data.jsonl'),
      purpose: 'fine-tune'
    });

    console.log(`File ID: ${file.id}`);
    console.log(`Filename: ${file.filename}`);
    console.log(`Size: ${file.bytes} bytes`);

    // The response includes dataset_id — use it to upload
    // more files to the same dataset.
    //
    // Optional '4minds' form field (JSON string):
    //   dataset_name  (string) - Custom name for the new dataset
    //   dataset_id    (integer) - Upload to an existing dataset
    //   training_type (string) - "graph" (default), "rl", or "sft"
    //   model_params  (object) - e.g. {learning_rate: 0.001}
  }

  uploadFile();
  ```

  ```javascript Node.js (Multi-File Upload) theme={null}
  const fs = require('fs');
  const path = require('path');

  const apiKey = 'YOUR_API_KEY';
  const baseUrl = 'https://api.4minds.ai/v1/files';

  async function uploadMultipleFiles() {
    // Step 1: Upload first file with a custom dataset name
    const form1 = new FormData();
    form1.append('file', new Blob([fs.readFileSync('document1.pdf')]), 'document1.pdf');
    form1.append('purpose', 'fine-tune');
    form1.append('4minds', JSON.stringify({
      dataset_name: 'My Training Data',
      training_type: 'graph'
    }));

    const response1 = await fetch(baseUrl, {
      method: 'POST',
      headers: { 'Authorization': `Bearer ${apiKey}` },
      body: form1
    });

    const result1 = await response1.json();
    const datasetId = result1.dataset_id;
    console.log(`Dataset created: ${datasetId}`);
    console.log(`First file: ${result1.id}`);

    // Step 2: Upload more files to the SAME dataset
    const moreFiles = ['document2.pdf', 'document3.pdf'];
    for (const filename of moreFiles) {
      const form = new FormData();
      form.append('file', new Blob([fs.readFileSync(filename)]), filename);
      form.append('purpose', 'fine-tune');
      form.append('4minds', JSON.stringify({ dataset_id: datasetId }));

      const response = await fetch(baseUrl, {
        method: 'POST',
        headers: { 'Authorization': `Bearer ${apiKey}` },
        body: form
      });

      const result = await response.json();
      console.log(`Uploaded ${filename}: ${result.id} (status: ${result.status})`);
    }

    // Step 3: Create a fine-tuning job — trains ALL files in dataset
    const OpenAI = require('openai');
    const openai = new OpenAI({ apiKey, baseURL: 'https://api.4minds.ai/v1' });

    const job = await openai.fineTuning.jobs.create({
      model: 'Gemma-12B AWQ',
      training_file: result1.id,
      suffix: 'my-custom-model'
    });
    console.log(`Fine-tuning job: ${job.id}, Status: ${job.status}`);
  }

  uploadMultipleFiles();
  ```
</CodeGroup>

***

### List All Uploaded Files

**GET** `/v1/files`

List all uploaded files with optional purpose filter (OpenAI-compatible).

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.4minds.ai/v1/files?purpose=fine-tune" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```
</CodeGroup>

***

### Get File Details

**GET** `/v1/files/{file_id}`

Retrieve details about a specific file (OpenAI-compatible).

#### Path Parameters

| Parameter | Type   | Required | Description                       |
| --------- | ------ | -------- | --------------------------------- |
| file\_id  | string | Yes      | The unique identifier of the file |

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET https://api.4minds.ai/v1/files/{file_id} \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```
</CodeGroup>

***

### Delete a File

**DELETE** `/v1/files/{file_id}`

Delete a file (OpenAI-compatible).

#### Path Parameters

| Parameter | Type   | Required | Description                                 |
| --------- | ------ | -------- | ------------------------------------------- |
| file\_id  | string | Yes      | The unique identifier of the file to delete |

<CodeGroup>
  ```bash cURL theme={null}
  curl -X DELETE https://api.4minds.ai/v1/files/{file_id} \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```
</CodeGroup>

***

## Fine-Tuning

OpenAI-compatible fine-tuning API. Create, monitor, and manage fine-tuning jobs to customize models with your training data.

> **Note:** Training processes ALL files in the dataset, not just the file referenced by `training_file`. Use `external_model_id` to deploy to an external model registered via `GET /v1/external-models`.

### Create a Fine-Tuning Job

**POST** `/v1/fine_tuning/jobs`

Create a fine-tuning job to train a model (OpenAI-compatible). Optionally pass `external_model_id` to target an external model from a connected integration.

#### Request Body

| Parameter           | Type    | Required | Description                                               |
| ------------------- | ------- | -------- | --------------------------------------------------------- |
| model               | string  | Yes      | The base model name to fine-tune (e.g. `"Gemma-12B AWQ"`) |
| training\_file      | string  | Yes      | The file ID to use for training                           |
| suffix              | string  | No       | Custom suffix for the fine-tuned model name               |
| external\_model\_id | integer | No       | ID of an external model from a connected integration      |

<CodeGroup>
  ```bash cURL theme={null}
  # Create fine-tuning job — trains ALL files in the dataset
  curl -X POST https://api.4minds.ai/v1/fine_tuning/jobs \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "Gemma-12B AWQ",
      "training_file": "file-abc123def456",
      "suffix": "my-custom-model"
    }'

  # With an external model (from connected integrations)
  curl -X POST https://api.4minds.ai/v1/fine_tuning/jobs \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "Gemma-12B AWQ",
      "training_file": "file-abc123def456",
      "suffix": "my-custom-model",
      "external_model_id": 42
    }'
  ```

  ```python Python theme={null}
  from openai import OpenAI

  client = OpenAI(
      api_key="YOUR_API_KEY",
      base_url="https://api.4minds.ai/v1"
  )

  # Create fine-tuning job
  job = client.fine_tuning.jobs.create(
      model="Gemma-12B AWQ",
      training_file="file-abc123def456",
      suffix="my-custom-model"
  )

  print(f"Job ID: {job.id}")
  print(f"Status: {job.status}")
  print(f"Model: {job.fine_tuned_model}")

  # With an external model (from connected integrations):
  # job = client.fine_tuning.jobs.create(
  #     model="Gemma-12B AWQ",
  #     training_file="file-abc123def456",
  #     suffix="my-custom-model",
  #     extra_body={"external_model_id": 42}
  # )
  ```

  ```javascript JavaScript theme={null}
  import OpenAI from 'openai';

  const openai = new OpenAI({
    apiKey: 'YOUR_API_KEY',
    baseURL: 'https://api.4minds.ai/v1'
  });

  async function createFineTuningJob() {
    const job = await openai.fineTuning.jobs.create({
      model: 'Gemma-12B AWQ',
      training_file: 'file-abc123def456',
      suffix: 'my-custom-model'
    });

    console.log(`Job ID: ${job.id}`);
    console.log(`Status: ${job.status}`);
    console.log(`Model: ${job.fine_tuned_model}`);

    // With an external model (from connected integrations):
    // Pass external_model_id in the body to target an external model
    // const job2 = await openai.fineTuning.jobs.create({
    //   model: 'Gemma-12B AWQ',
    //   training_file: 'file-abc123def456',
    //   suffix: 'my-custom-model',
    //   body: { external_model_id: 42 }
    // });
  }

  createFineTuningJob();
  ```

  ```javascript Node.js theme={null}
  const OpenAI = require('openai');

  const openai = new OpenAI({
    apiKey: 'YOUR_API_KEY',
    baseURL: 'https://api.4minds.ai/v1'
  });

  async function createFineTuningJob() {
    const job = await openai.fineTuning.jobs.create({
      model: 'Gemma-12B AWQ',
      training_file: 'file-abc123def456',
      suffix: 'my-custom-model'
    });

    console.log(`Job ID: ${job.id}`);
    console.log(`Status: ${job.status}`);
    console.log(`Model: ${job.fine_tuned_model}`);

    // With an external model (from connected integrations):
    // Pass external_model_id in the body to target an external model
    // const job2 = await openai.fineTuning.jobs.create({
    //   model: 'Gemma-12B AWQ',
    //   training_file: 'file-abc123def456',
    //   suffix: 'my-custom-model',
    //   body: { external_model_id: 42 }
    // });
  }

  createFineTuningJob();
  ```
</CodeGroup>

***

### List All Fine-Tuning Jobs

**GET** `/v1/fine_tuning/jobs`

List all fine-tuning jobs (OpenAI-compatible).

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET https://api.4minds.ai/v1/fine_tuning/jobs \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```
</CodeGroup>

***

### Get Fine-Tuning Job Details

**GET** `/v1/fine_tuning/jobs/{job_id}`

Get fine-tuning job details (OpenAI-compatible).

#### Path Parameters

| Parameter | Type   | Required | Description                                  |
| --------- | ------ | -------- | -------------------------------------------- |
| job\_id   | string | Yes      | The unique identifier of the fine-tuning job |

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET https://api.4minds.ai/v1/fine_tuning/jobs/{job_id} \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```
</CodeGroup>

***

### List Fine-Tune Categories

**GET** `/v1/fine-tune-categories`

List available fine-tune categories for domain-specific prompting (4minds extension).

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET https://api.4minds.ai/v1/fine-tune-categories \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```
</CodeGroup>

***

### Cancel a Fine-Tuning Job

**POST** `/v1/fine_tuning/jobs/{job_id}/cancel`

Cancel a running fine-tuning job (OpenAI-compatible).

#### Path Parameters

| Parameter | Type   | Required | Description                                            |
| --------- | ------ | -------- | ------------------------------------------------------ |
| job\_id   | string | Yes      | The unique identifier of the fine-tuning job to cancel |

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.4minds.ai/v1/fine_tuning/jobs/{job_id}/cancel \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```
</CodeGroup>

***

## Datasets (OpenAI-Compatible Extension)

OpenAI-compatible datasets API. Create, list, retrieve, delete, and import datasets. Datasets group training files together for fine-tuning jobs. You can also import datasets directly from connected integrations.

### List All Datasets

**GET** `/v1/datasets`

List all datasets with their file counts and status.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET https://api.4minds.ai/v1/datasets \
    -H "Authorization: Bearer YOUR_API_KEY"

  # Example response:
  # {
  #   "object": "list",
  #   "data": [
  #     {
  #       "id": 1234,
  #       "name": "Medical Research Data",
  #       "file_count": 3,
  #       "total_bytes": 524288,
  #       "status": "ready",
  #       "created_at": "2025-03-01T12:00:00Z"
  #     }
  #   ]
  # }
  ```

  ```python Python theme={null}
  import requests

  url = "https://api.4minds.ai/v1/datasets"
  headers = {"Authorization": "Bearer YOUR_API_KEY"}

  response = requests.get(url, headers=headers)
  result = response.json()

  for dataset in result["data"]:
      print(f"ID: {dataset['id']}")
      print(f"  Name: {dataset['name']}")
      print(f"  Files: {dataset['file_count']}")
      print(f"  Status: {dataset['status']}")
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.4minds.ai/v1/datasets', {
    headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
  });

  const result = await response.json();

  for (const dataset of result.data) {
    console.log(`ID: ${dataset.id}`);
    console.log(`  Name: ${dataset.name}`);
    console.log(`  Files: ${dataset.file_count}`);
    console.log(`  Status: ${dataset.status}`);
  }
  ```

  ```javascript Node.js theme={null}
  const response = await fetch('https://api.4minds.ai/v1/datasets', {
    headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
  });

  const result = await response.json();

  for (const dataset of result.data) {
    console.log(`ID: ${dataset.id}`);
    console.log(`  Name: ${dataset.name}`);
    console.log(`  Files: ${dataset.file_count}`);
    console.log(`  Status: ${dataset.status}`);
  }
  ```
</CodeGroup>

***

### Create a New Dataset

**POST** `/v1/datasets`

Create a new empty dataset to group training files.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.4minds.ai/v1/datasets \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"name": "My New Dataset"}'
  ```
</CodeGroup>

***

### Import a Dataset

**POST** `/v1/datasets/import`

Import a dataset directly from a connected integration (e.g. Databricks, S3, Azure Blob).

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.4minds.ai/v1/datasets/import \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "integration_id": "your-integration-id",
      "source_path": "s3://your-bucket/your-data/"
    }'
  ```
</CodeGroup>

***

### Get Dataset Details

**GET** `/v1/datasets/{id}`

Get details of a specific dataset including its files.

#### Path Parameters

| Parameter | Type   | Required | Description                          |
| --------- | ------ | -------- | ------------------------------------ |
| id        | string | Yes      | The unique identifier of the dataset |

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET https://api.4minds.ai/v1/datasets/{id} \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```
</CodeGroup>

***

### Delete a Dataset

**DELETE** `/v1/datasets/{id}`

Delete a dataset and optionally its associated files.

#### Path Parameters

| Parameter | Type   | Required | Description                          |
| --------- | ------ | -------- | ------------------------------------ |
| id        | string | Yes      | The unique identifier of the dataset |

<CodeGroup>
  ```bash cURL theme={null}
  curl -X DELETE https://api.4minds.ai/v1/datasets/{id} \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```
</CodeGroup>

***

## Authentication

All API requests require authentication using a Bearer token in the Authorization header:

```text theme={null}
Authorization: Bearer YOUR_API_KEY
```

You can obtain your API key from your 4MINDS dashboard.

***

## OpenAI SDK Quick Setup

Since this API is OpenAI-compatible, you can use the official OpenAI SDK by setting the `base_url` to `https://api.4minds.ai/v1`:

```python Python theme={null}
from openai import OpenAI

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.4minds.ai/v1"
)
```

```javascript JavaScript / Node.js theme={null}
import OpenAI from 'openai'; // or: const OpenAI = require('openai');

const openai = new OpenAI({
  apiKey: 'YOUR_API_KEY',
  baseURL: 'https://api.4minds.ai/v1'
});
```

***

## Response Format

All responses are returned in JSON format and follow OpenAI-compatible response structures.

### Success Response

```json theme={null}
{
  "object": "list",
  "data": [ ... ]
}
```

### Error Response

```json theme={null}
{
  "error": {
    "message": "Error description",
    "type": "invalid_request_error",
    "code": "error_code"
  }
}
```

***
