Skip to content

Go SDK

Idiomatic Go client with context support and strong typing.


Installation

go get github.com/archivus/archivus-go

Quick Start

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/archivus/archivus-go"
)

func main() {
    client := archivus.NewClient(
        os.Getenv("ARCHIVUS_API_KEY"),
        "your-tenant",
    )

    ctx := context.Background()

    // Upload document
    file, _ := os.Open("contract.pdf")
    document, err := client.Documents.Upload(ctx, &archivus.UploadOptions{
        File: file,
        EnableAI: true,
    })
    if err != nil {
        log.Fatal(err)
    }

    // Search
    results, _ := client.Search.Query(ctx, "contract terms", nil)

    // Chat
    session, _ := client.Chat.CreateSession(ctx, &archivus.ChatSessionOptions{
        DocumentID: document.ID,
    })

    answer, _ := client.Chat.Ask(ctx, session.ID, "What are the key terms?")
    fmt.Println(answer.Content)
}

API Reference

Client Configuration

import "github.com/archivus/archivus-go"

client := archivus.NewClient(
    "your-api-key",
    "your-tenant",
    archivus.WithBaseURL("https://api.archivus.app/api/v1"),
    archivus.WithMaxRetries(3),
    archivus.WithTimeout(30 * time.Second),
)

Documents

// List documents
docs, err := client.Documents.List(ctx, &archivus.ListOptions{
    Page: 1,
    Limit: 20,
    FolderID: "folder_abc123",
})

// Get document
doc, err := client.Documents.Get(ctx, "doc_abc123")

// Upload document
file, _ := os.Open("contract.pdf")
doc, err := client.Documents.Upload(ctx, &archivus.UploadOptions{
    File: file,
    FolderID: "folder_abc123",
    EnableAI: true,
    Tags: []string{"contract", "legal"},
})

// Update document
updated, err := client.Documents.Update(ctx, "doc_abc123", &archivus.UpdateOptions{
    Filename: "new-name.pdf",
    Tags: []string{"updated"},
})

// Delete document
err := client.Documents.Delete(ctx, "doc_abc123")

// Download document
reader, err := client.Documents.Download(ctx, "doc_abc123")
defer reader.Close()

// Copy to file
file, _ := os.Create("output.pdf")
io.Copy(file, reader)

// Get content
content, err := client.Documents.GetContent(ctx, "doc_abc123")
// Basic search
results, err := client.Search.Query(ctx, "contract terms", &archivus.SearchOptions{
    Mode: archivus.SearchModeSemantic,
    Limit: 10,
    FolderID: "folder_abc123",
})

// Enhanced search (Pro+)
results, err := client.Search.Enhanced(ctx, &archivus.EnhancedSearchOptions{
    Query: "Find contracts expiring in Q4",
    Filters: &archivus.SearchFilters{
        Tags: []string{"contract"},
        DateRange: &archivus.DateRange{
            Start: "2026-10-01",
            End: "2026-12-31",
        },
    },
})

Chat

// Create session
session, err := client.Chat.CreateSession(ctx, &archivus.ChatSessionOptions{
    DocumentID: "doc_abc123",
    Name: "Analysis",
})

// Ask question
answer, err := client.Chat.Ask(ctx, session.ID, "What are the key terms?")

// RAG query (Pro+)
answer, err := client.Chat.AskRAG(ctx, session.ID, "Find all contracts")

// Get messages
messages, err := client.Chat.GetMessages(ctx, session.ID, &archivus.MessagesOptions{
    Limit: 50,
})

// List sessions
sessions, err := client.Chat.ListSessions(ctx, nil)

// Delete session
err := client.Chat.DeleteSession(ctx, session.ID)

Webhooks

// Create webhook
webhook, err := client.Webhooks.Create(ctx, &archivus.WebhookOptions{
    URL: "https://yourapp.com/webhooks",
    Events: []string{"document.processed", "document.failed"},
    Secret: "your-secret",
})

// List webhooks
webhooks, err := client.Webhooks.List(ctx)

// Update webhook
err := client.Webhooks.Update(ctx, "webhook_abc123", &archivus.WebhookOptions{
    Events: []string{"document.processed"},
})

// Delete webhook
err := client.Webhooks.Delete(ctx, "webhook_abc123")

Error Handling

import "github.com/archivus/archivus-go/errors"

doc, err := client.Documents.Get(ctx, "doc_abc123")
if err != nil {
    switch e := err.(type) {
    case *errors.NotFoundError:
        log.Println("Document not found")
    case *errors.RateLimitError:
        log.Printf("Rate limit exceeded, retry after: %v", e.RetryAfter)
    case *errors.ArchivusError:
        log.Printf("API error: %s - %s", e.Code, e.Message)
    default:
        log.Printf("Unexpected error: %v", err)
    }
    return err
}

Context Support

All methods accept a context for cancellation and timeouts:

// With timeout
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

doc, err := client.Documents.Upload(ctx, &archivus.UploadOptions{
    File: file,
    EnableAI: true,
})

// With cancellation
ctx, cancel := context.WithCancel(context.Background())
go func() {
    time.Sleep(5 * time.Second)
    cancel()  // Cancel after 5 seconds
}()

results, err := client.Search.Query(ctx, "query", nil)

Webhook Verification

package main

import (
    "net/http"

    "github.com/archivus/archivus-go/webhooks"
)

func webhookHandler(w http.ResponseWriter, r *http.Request) {
    signature := r.Header.Get("X-Archivus-Signature")
    payload, _ := io.ReadAll(r.Body)

    if !webhooks.VerifySignature(payload, signature, webhookSecret) {
        http.Error(w, "Invalid signature", http.StatusUnauthorized)
        return
    }

    var event webhooks.Event
    json.Unmarshal(payload, &event)

    switch event.Type {
    case webhooks.DocumentProcessed:
        handleDocumentProcessed(event.Data)
    case webhooks.DocumentFailed:
        handleDocumentFailed(event.Data)
    }

    w.WriteHeader(http.StatusOK)
    json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
}

Streaming

// Stream document download
reader, err := client.Documents.Download(ctx, "doc_abc123")
if err != nil {
    log.Fatal(err)
}
defer reader.Close()

// Stream to response
w.Header().Set("Content-Type", "application/pdf")
w.Header().Set("Content-Disposition", "attachment; filename=document.pdf")
io.Copy(w, reader)

Concurrency

// Upload multiple documents concurrently
var wg sync.WaitGroup
files := []string{"doc1.pdf", "doc2.pdf", "doc3.pdf"}

for _, filename := range files {
    wg.Add(1)
    go func(name string) {
        defer wg.Done()

        file, _ := os.Open(name)
        defer file.Close()

        doc, err := client.Documents.Upload(ctx, &archivus.UploadOptions{
            File: file,
            EnableAI: true,
        })
        if err != nil {
            log.Printf("Failed to upload %s: %v", name, err)
            return
        }

        log.Printf("Uploaded %s: %s", name, doc.ID)
    }(filename)
}

wg.Wait()

Testing

import (
    "testing"

    "github.com/archivus/archivus-go"
    "github.com/archivus/archivus-go/mock"
)

func TestUploadDocument(t *testing.T) {
    mockClient := mock.NewClient()
    mockClient.Documents.On("Upload", mock.Anything, mock.Anything).
        Return(&archivus.Document{
            ID: "doc_test123",
            Filename: "test.pdf",
        }, nil)

    doc, err := mockClient.Documents.Upload(context.Background(), nil)
    if err != nil {
        t.Fatal(err)
    }

    if doc.ID != "doc_test123" {
        t.Errorf("Expected doc_test123, got %s", doc.ID)
    }
}

Next Steps