# Upload filer til en Vektorbutik

{% openapi src="<https://github.com/skydeckai/rememberizer-docs/blob/production/da/.gitbook/assets/rememberizer_openapi.yml>" path="/vector-stores/{vector-store-id}/documents/upload" method="post" %}
<https://github.com/skydeckai/rememberizer-docs/blob/production/da/.gitbook/assets/rememberizer_openapi.yml>
{% endopenapi %}

## Eksempelanmodninger

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X POST \
  https://api.rememberizer.ai/api/v1/vector-stores/vs_abc123/documents/upload \
  -H "x-api-key: DIN_API_NØGLE" \
  -F "files=@/sti/til/dokument1.pdf" \
  -F "files=@/sti/til/dokument2.docx"
```

{% hint style="info" %}
Erstat `DIN_API_NØGLE` med din faktiske Vector Store API-nøgle, `vs_abc123` med dit Vector Store ID, og angiv stierne til dine lokale filer.
{% endhint %}
{% endtab %}

{% tab title="JavaScript" %}

```javascript
const uploadFiles = async (vectorStoreId, files) => {
  const formData = new FormData();
  
  // Tilføj flere filer til formular data
  for (const file of files) {
    formData.append('files', file);
  }
  
  const response = await fetch(`https://api.rememberizer.ai/api/v1/vector-stores/${vectorStoreId}/documents/upload`, {
    method: 'POST',
    headers: {
      'x-api-key': 'DIN_API_NØGLE'
      // Bemærk: Sæt ikke Content-Type header, den vil blive sat automatisk med den korrekte grænse
    },
    body: formData
  });
  
  const data = await response.json();
  console.log(data);
};

// Eksempel på brug med filinput-element
const fileInput = document.getElementById('fileInput');
uploadFiles('vs_abc123', fileInput.files);
```

{% hint style="info" %}
Erstat `DIN_API_NØGLE` med din faktiske Vector Store API-nøgle og `vs_abc123` med dit Vector Store ID.
{% endhint %}
{% endtab %}

{% tab title="Python" %}

```python
import requests

def upload_files(vector_store_id, file_paths):
    headers = {
        "x-api-key": "DIN_API_NØGLE"
    }
    
    files = [('files', (file_path.split('/')[-1], open(file_path, 'rb'))) for file_path in file_paths]
    
    response = requests.post(
        f"https://api.rememberizer.ai/api/v1/vector-stores/{vector_store_id}/documents/upload",
        headers=headers,
        files=files
    )
    
    data = response.json()
    print(data)

upload_files('vs_abc123', ['/sti/til/dokument1.pdf', '/sti/til/dokument2.docx'])
```

{% hint style="info" %}
Erstat `DIN_API_NØGLE` med din faktiske Vector Store API-nøgle, `vs_abc123` med dit Vector Store ID, og angiv stierne til dine lokale filer.
{% endhint %}
{% endtab %}

{% tab title="Ruby" %}
\`\`\`ruby require 'net/http' require 'uri' require 'json'

def upload\_files(vector\_store\_id, file\_paths) uri = URI("<https://api.rememberizer.ai/api/v1/vector-stores/#{vector\\_store\\_id}/documents/upload>")

## Opret et nyt HTTP-objekt

http = Net::HTTP.new(uri.host, uri.port) http.use\_ssl = true

## Opret en multipart-form anmodning

request = Net::HTTP::Post.new(uri) request\['x-api-key'] = 'DIN\_API\_NØGLE'

## Opret en multipart grænse

boundary = "RubyFormBoundary#{rand(1000000)}" request\['Content-Type'] = "multipart/form-data; boundary=#{boundary}"

## Byg anmodningskroppen

body = \[] file\_paths.each do |file\_path| file\_name = File.basename(file\_path) file\_content = File.read(file\_path, mode: 'rb')

```
body << "--#{boundary}\r\n"
body << "Content-Disposition: form-data; name=\"files\"; filename=\"#{file_name}\"\r\n"
body << "Content-Type: #{get_content_type(file_name)}\r\n\r\n"
body << file_content
body << "\r\n"
```

end body << "--#{boundary}--\r\n"

request.body = body.join

## Send anmodningen

response = http.request(request)

## Parse og returner svaret

JSON.parse(response.body) end

```

# Hjælpefunktion til at bestemme indholdstype
def get_content_type(filename)
  ext = File.extname(filename).downcase
  case ext
  when '.pdf'  then 'application/pdf'
  when '.doc'  then 'application/msword'
  when '.docx' then 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
  when '.txt'  then 'text/plain'
  when '.md'   then 'text/markdown'
  when '.json' then 'application/json'
  else 'application/octet-stream'
  end
end

# Eksempel på brug
resultat = upload_files('vs_abc123', ['/path/to/document1.pdf', '/path/to/document2.docx'])
puts resultat
```

{% hint style="info" %} Erstat `YOUR_API_KEY` med din faktiske Vector Store API-nøgle, `vs_abc123` med dit Vector Store ID, og angiv stierne til dine lokale filer. {% endhint %} {% endtab %} {% endtabs %}

### Sti Parametre

| Parameter       | Type   | Beskrivelse                                                         |
| --------------- | ------ | ------------------------------------------------------------------- |
| vector-store-id | string | **Påkrævet.** ID'en på vektorbutikken, som filer skal uploades til. |

### Anmodningskrop

Denne endpoint accepterer en `multipart/form-data` anmodning med en eller flere filer i `files` feltet.

### Svarformat

```json
{
  "documents": [
    {
      "id": 1234,
      "name": "document1.pdf",
      "type": "application/pdf",
      "size": 250000,
      "status": "behandler",
      "created": "2023-06-15T10:15:00Z",
      "vector_store": "vs_abc123"
    },
    {
      "id": 1235,
      "name": "document2.docx",
      "type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
      "size": 180000,
      "status": "behandler",
      "created": "2023-06-15T10:15:00Z",
      "vector_store": "vs_abc123"
    }
  ],
  "errors": []
}
```

Hvis nogle filer ikke kan uploades, vil de blive listet i `errors`-arrayet:

```json
{
  "documents": [
    {
      "id": 1234,
      "name": "document1.pdf",
      "type": "application/pdf",
      "size": 250000,
      "status": "behandler",
      "created": "2023-06-15T10:15:00Z",
      "vector_store": "vs_abc123"
    }
  ],
  "errors": [
    {
      "file": "document2.docx",
      "error": "Filformat ikke understøttet"
    }
  ]
}
```

### Godkendelse

Denne endpoint kræver godkendelse ved hjælp af en API-nøgle i `x-api-key` headeren.

### Understøttede filformater

* PDF (`.pdf`)
* Microsoft Word (`.doc`, `.docx`)
* Microsoft Excel (`.xls`, `.xlsx`)
* Microsoft PowerPoint (`.ppt`, `.pptx`)
* Tekstfiler (`.txt`)
* Markdown (`.md`)
* JSON (`.json`)
* HTML (`.html`, `.htm`)

### Filstørrelsesgrænser

* Individuel filstørrelsesgrænse: 50MB
* Total anmodningsstørrelsesgrænse: 100MB
* Maksimalt antal filer pr. anmodning: 20

### Fejlrespons

| Statuskode | Beskrivelse                                                            |
| ---------- | ---------------------------------------------------------------------- |
| 400        | Bad Request - Ingen filer angivet eller ugyldigt anmodningsformat      |
| 401        | Uautoriseret - Ugyldig eller manglende API-nøgle                       |
| 404        | Ikke Fundet - Vektorbutik ikke fundet                                  |
| 413        | Payload For Stor - Filer overstiger størrelsesgrænsen                  |
| 415        | Uunderstøttet Mediatype - Filformat understøttes ikke                  |
| 500        | Intern Serverfejl                                                      |
| 207        | Multi-Status - Nogle filer blev uploadet med succes, men andre fejlede |

### Behandlingsstatus

Filer accepteres oprindeligt med en status på `behandling`. Du kan tjekke behandlingsstatus for dokumenterne ved hjælp af [Hent en liste over dokumenter i en vektorbutik](/da/udviklerressourcer/api-docs/vector-store/get-a-list-of-documents-in-a-vector-store.md) endpointet. Den endelige status vil være en af:

* `færdig`: Dokumentet blev behandlet med succes
* `fejl`: Der opstod en fejl under behandlingen
* `behandling`: Dokumentet bliver stadig behandlet

Behandlingstiden afhænger af filstørrelse og kompleksitet. Typisk behandlingstid er mellem 30 sekunder og 5 minutter pr. dokument.

### Batch Operationer

For effektivt at uploade flere filer til din Vector Store, understøtter Rememberizer batch operationer. Denne tilgang hjælper med at optimere ydeevnen, når man arbejder med et stort antal dokumenter.

#### Batch Upload Implementering

{% tabs %} {% tab title="Python" %}

```python
import os
import requests
import time
import concurrent.futures
from pathlib import Path

def batch_upload_to_vector_store(vector_store_id, folder_path, batch_size=5, file_types=None):
    """
    Upload alle filer fra en mappe til et Vector Store i batches
    
    Args:
        vector_store_id: ID for vector store
        folder_path: Sti til mappen, der indeholder filer til upload
        batch_size: Antal filer der skal uploades i hver batch
        file_types: Valgfri liste over filtyper til filtrering (f.eks. ['.pdf', '.docx'])
        
    Returns:
        Liste over uploadresultater
    """
    api_key = "YOUR_API_KEY"
    headers = {"x-api-key": api_key}
    
    # Hent liste over filer i mappen
    files = []
    for entry in os.scandir(folder_path):
        if entry.is_file():
            file_path = Path(entry.path)
            # Filtrer efter filtype hvis angivet
            if file_types is None or file_path.suffix.lower() in file_types:
                files.append(file_path)
    
    print(f"Fundet {len(files)} filer til upload")
    results = []
    
    # Behandl filer i batches
    for i in range(0, len(files), batch_size):
        batch = files[i:i+batch_size]
        print(f"Behandler batch {i//batch_size + 1}/{(len(files) + batch_size - 1)//batch_size}: {len(batch)} filer")
        
        # Upload batch
        upload_files = []
        for file_path in batch:
            upload_files.append(('files', (file_path.name, open(file_path, 'rb'))))
        
        try:
            response = requests.post(
                f"https://api.rememberizer.ai/api/v1/vector-stores/{vector_store_id}/documents/upload",
                headers=headers,
                files=upload_files
            )
            
            # Luk alle filhåndtag
            for _, (_, file_obj) in upload_files:
                file_obj.close()
            
            if response.status_code in (200, 201, 207):
                batch_result = response.json()
                results.append(batch_result)
                print(f"Batch uploadet med succes - {len(batch_result.get('documents', []))} dokumenter behandlet")
                
                # Tjek for fejl
                if batch_result.get('errors') and len(batch_result['errors']) > 0:
                    print(f"Fejl opstået: {len(batch_result['errors'])}")
                    for error in batch_result['errors']:
                        print(f"- {error['file']}: {error['error']}")
            else:
                print(f"Batch upload fejlede med statuskode {response.status_code}: {response.text}")
                results.append({"error": f"Batch fejlede: {response.text}"})
                
        except Exception as e:
            print(f"Undtagelse under batch upload: {str(e)}")
            results.append({"error": str(e)})
            
            # Luk eventuelle resterende filhåndtag i tilfælde af undtagelse
            for _, (_, file_obj) in upload_files:
                try:
                    file_obj.close()
                except:
                    pass
        
        # Rate limiting - pause mellem batches
        if i + batch_size < len(files):
            print("Pauser før næste batch...")
            time.sleep(2)
    
    return results

# Eksempel på brug
results = batch_upload_to_vector_store(
    'vs_abc123',
    '/path/to/documents/folder',
    batch_size=5,
    file_types=['.pdf', '.docx', '.txt']
)
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
/**
 * Upload filer til en Vector Store i batches
 * 
 * @param {string} vectorStoreId - ID for Vector Store
 * @param {FileList|File[]} files - Filer der skal uploades
 * @param {Object} options - Konfigurationsmuligheder
 * @returns {Promise<Array>} - Liste over uploadresultater
 */
async function batchUploadToVectorStore(vectorStoreId, files, options = {}) {
  const {
    batchSize = 5,
    delayBetweenBatches = 2000,
    onProgress = null
  } = options;
  
  const apiKey = 'YOUR_API_KEY';
  const results = [];
  const fileList = Array.from(files);
  const totalBatches = Math.ceil(fileList.length / batchSize);
  
  console.log(`Forbereder at uploade ${fileList.length} filer i ${totalBatches} batches`);
  
  // Behandl filer i batches
  for (let i = 0; i < fileList.length; i += batchSize) {
    const batch = fileList.slice(i, i + batchSize);
    const batchNumber = Math.floor(i / batchSize) + 1;
    
    console.log(`Behandler batch ${batchNumber}/${totalBatches}: ${batch.length} filer`);
    
    if (onProgress) {
      onProgress({
        currentBatch: batchNumber,
        totalBatches: totalBatches,
        filesInBatch: batch.length,
        totalFiles: fileList.length,
        completedFiles: i
      });
    }
    
    // Opret FormData for denne batch
    const formData = new FormData();
    batch.forEach(file => {
      formData.append('files', file);
    });
    
    try {
      const response = await fetch(
        `https://api.rememberizer.ai/api/v1/vector-stores/${vectorStoreId}/documents/upload`,
        {
          method: 'POST',
          headers: {
            'x-api-key': apiKey
          },
          body: formData
        }
      );
      
      if (response.ok) {
        const batchResult = await response.json();
        results.push(batchResult);
        
        console.log(`Batch uploadet med succes - ${batchResult.documents?.length || 0} dokumenter behandlet`);
        
        // Tjek for fejl
        if (batchResult.errors && batchResult.errors.length > 0) {
          console.warn(`Fejl opstået: ${batchResult.errors.length}`);
          batchResult.errors.forEach(error => {
            console.warn(`- ${error.file}: ${error.error}`);
          });
        }
      } else {
        console.error(`Batch upload fejlede med status ${response.status}: ${await response.text()}`);
        results.push({ error: `Batch fejlede med status: ${response.status}` });
      }
    } catch (error) {
      console.error(`Undtagelse under batch upload: ${error.message}`);
      results.push({ error: error.message });
    }
    
    // Tilføj forsinkelse mellem batches for at undgå rate limiting
    if (i + batchSize < fileList.length) {
      console.log(`Pause i ${delayBetweenBatches}ms før næste batch...`);
      await new Promise(resolve => setTimeout(resolve, delayBetweenBatches));
    }
  }
  
  console.log(`Upload fuldført. Behandlet ${fileList.length} filer.`);
  return results;
}

// Eksempel på brug med filinput-element
document.getElementById('upload-button').addEventListener('click', async () => {
  const fileInput = document.getElementById('file-input');
  const vectorStoreId = 'vs_abc123';
  
  const progressBar = document.getElementById('progress-bar');
  
  try {
    const results = await batchUploadToVectorStore(vectorStoreId, fileInput.files, {
      batchSize: 5,
      onProgress: (progress) => {
        // Opdater progress UI
        const percentage = Math.round((progress.completedFiles / progress.totalFiles) * 100);
        progressBar.style.width = `${percentage}%`;
        progressBar.textContent = `${percentage}% (Batch ${progress.currentBatch}/${progress.totalBatches})`;
      }
    });
    
    console.log('Færdige uploadresultater:', results);
  } catch (error) {
    console.error('Upload fejlede:', error);
  }
});
```

{% endtab %}

{% tab title="Ruby" %}

```

ruby
require 'net/http'
require 'uri'
require 'json'
require 'mime/types'

# Upload filer til et Vektorbutik i batcher
#
# @param vector_store_id [String] ID på Vector Store
# @param folder_path [String] Sti til mappen, der indeholder filer, der skal uploades
# @param batch_size [Integer] Antal filer, der skal uploades i hver batch
# @param file_types [Array<String>] Valgfri array af filudvidelser at filtrere efter
# @param delay_between_batches [Float] Sekunder at vente mellem batcher
# @return [Array] Liste over uploadresultater
def batch_upload_to_vector_store(vector_store_id, folder_path, batch_size: 5, file_types: nil, delay_between_batches: 2.0)
  api_key = 'YOUR_API_KEY'
  results = []
  
  # Hent liste over filer i mappen
  files = Dir.entries(folder_path)
    .select { |f| File.file?(File.join(folder_path, f)) }
    .select { |f| file_types.nil? || file_types.include?(File.extname(f).downcase) }
    .map { |f| File.join(folder_path, f) }
  
  puts "Fundet #{files.count} filer til upload"
  total_batches = (files.count.to_f / batch_size).ceil
  
  # Behandl filer i batches
  files.each_slice(batch_size).with_index do |batch, batch_index|
    puts "Behandler batch #{batch_index + 1}/#{total_batches}: #{batch.count} filer"
    
    # Forbered HTTP-anmodningen
    uri = URI("https://api.rememberizer.ai/api/v1/vector-stores/#{vector_store_id}/documents/upload")
    request = Net::HTTP::Post.new(uri)
    request['x-api-key'] = api_key
    
    # Opret en multipart form grænse
    boundary = "RubyBoundary#{rand(1000000)}"
    request['Content-Type'] = "multipart/form-data; boundary=#{boundary}"
    
    # Byg anmodningskroppen
    body = []
    batch.each do |file_path|
      file_name = File.basename(file_path)
      mime_type = MIME::Types.type_for(file_path).first&.content_type || 'application/octet-stream'
      
      begin
        file_content = File.binread(file_path)
        
        body << "--#{boundary}\r\n"
        body << "Content-Disposition: form-data; name=\"files\"; filename=\"#{file_name}\"\r\n"
        body << "Content-Type: #{mime_type}\r\n\r\n"
        body << file_content
        body << "\r\n"
      rescue => e
        puts "Fejl ved læsning af fil #{file_path}: #{e.message}"
      end
    end
    body << "--#{boundary}--\r\n"
    
    request.body = body.join
    
    # Send anmodningen
    begin
      http = Net::HTTP.new(uri.host, uri.port)
      http.use_ssl = true
      response = http.request(request)
      
      if response.code.to_i == 200 || response.code.to_i == 201 || response.code.to_i == 207
        batch_result = JSON.parse(response.body)
        results << batch_result
        
        puts "Batch uploadet med succes - #{batch_result['documents']&.count || 0} dokumenter behandlet"
        
        # Tjek for fejl
        if batch_result['errors'] && !batch_result['errors'].empty?
          puts "Fejl opstået: #{batch_result['errors'].count}"
          batch_result['errors'].each do |error|
            puts "- #{error['file']}: #{error['error']}"
          end
        end
      else
        puts "Batch upload mislykkedes med statuskode #{response.code}: #{response.body}"
        results << { "error" => "Batch mislykkedes: #{response.body}" }
      end
    rescue => e
      puts "Undtagelse under batch upload: #{e.message}"
      results << { "error" => e.message }
    end
    
    # Rate limiting - pause mellem batches
    if batch_index < total_batches - 1
      puts "Pauser i #{delay_between_batches} sekunder før næste batch..."
      sleep(delay_between_batches)
    end
  end
  
  puts "Upload fuldført. Behandlet #{files.count} filer."
  results
end

# Eksempel på brug
results = batch_upload_to_vector_store(
  'vs_abc123',
  '/path/to/documents/folder',
  batch_size: 5,
  file_types: ['.pdf', '.docx', '.txt'],
  delay_between_batches: 2.0
)
```

{% endtab %}
{% endtabs %}

### Batch Upload Bedste Praksis

For at optimere ydeevne og pålidelighed ved upload af store mængder filer:

1. **Håndter Batch Størrelse**: Hold batch størrelser mellem 5-10 filer for optimal ydeevne. For mange filer i en enkelt anmodning øger risikoen for timeout.
2. **Implementer Rate Limiting**: Tilføj forsinkelser mellem batches (2-3 sekunder anbefales) for at undgå at ramme API rate grænser.
3. **Tilføj Fejl Retry Logik**: For produktionssystemer, implementer retry logik for mislykkede uploads med eksponentiel tilbageholdelse.
4. **Valider Filtyper**: Forfiltrer filer for at sikre, at de er understøttede typer, før upload forsøges.
5. **Overvåg Batch Fremskridt**: For brugerorienterede applikationer, giv fremskridtsfeedback om batch operationer.
6. **Håndter Delvis Succes**: API'en kan returnere en 207 statuskode for delvis succes. Tjek altid individuelle dokumentstatusser.
7. **Ryd Op i Ressourcer**: Sørg for, at alle filhåndtag er korrekt lukket, især når der opstår fejl.
8. **Paralleliser Klogt**: For meget store uploads (tusinder af filer), overvej flere samtidige batch processer, der målretter forskellige vektorbutikker, og kombiner derefter resultaterne senere, hvis nødvendigt.
9. **Implementer Checksums**: For kritiske data, verificer filintegritet før og efter upload med checksums.
10. **Log Omfattende Resultater**: Oprethold detaljerede logs over alle upload operationer til fejlfinding.

Ved at følge disse bedste praksis kan du effektivt håndtere storskala dokumentindtagelse i dine vektorbutikker.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.rememberizer.ai/da/udviklerressourcer/api-docs/vector-store/upload-files-to-a-vector-store.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
