Official SDK

Go

Idiomatic Go with context support and proper error handling. Designed for production use with automatic retries and clean interfaces.

Go 1.21+MIT licensed

Rename PDFs, split multi-page documents, and extract structured data using the official Go SDK for Renamed.to.

  1. 1Run go get github.com/renamed-to/renamed-sdk/sdks/go to install
  2. 2Pass context.Context to Rename(), PDFSplit(), or Extract() with PDF bytes
  3. 3Receive strongly-typed results with idiomatic Go error handling

MIT licensed, open source on GitHub, published on Go Modules.

Installation

Shell
go get github.com/renamed-to/renamed-sdk/sdks/go

Quickstart

Initialize the client and start making API calls.

main.go
Go
package mainimport (    "context"    "fmt"    "os"    renamed "github.com/renamed-to/renamed-sdk/sdks/go")func main() {    // Initialize the client    client := renamed.NewClient(os.Getenv("RENAMED_API_KEY"))    ctx := context.Background()    // Read a PDF file    data, _ := os.ReadFile("invoice.pdf")    // Rename the PDF    result, err := client.Rename(ctx, data)    if err != nil {        panic(err)    }    fmt.Println(result.SuggestedFilename)    // -> "2024-01-15_AcmeCorp_INV-1234.pdf"    // Split a multi-page PDF    docs, _ := os.ReadFile("documents.pdf")    job, _ := client.PDFSplit(ctx, docs, renamed.SplitOptions{        Mode: "smart",    })    fmt.Println(job.Documents)    // Extract structured data    receipt, _ := os.ReadFile("receipt.pdf")    extracted, _ := client.Extract(ctx, receipt)    fmt.Println(extracted)}

Rename a PDF

Pass PDF bytes to get an AI-generated filename. Use custom instructions to control the naming format.

rename.go
Go
package mainimport (    "context"    "fmt"    "log"    "os"    "time"    renamed "github.com/renamed-to/renamed-sdk/sdks/go")func main() {    // Initialize the client    client := renamed.NewClient(os.Getenv("RENAMED_API_KEY"))    // Create a context with timeout    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)    defer cancel()    // Read the PDF file    data, err := os.ReadFile("./documents/invoice.pdf")    if err != nil {        log.Fatalf("failed to read file: %v", err)    }    // Rename the PDF    result, err := client.Rename(ctx, data)    if err != nil {        log.Fatalf("rename failed: %v", err)    }    fmt.Printf("Suggested filename: %s\n", result.SuggestedFilename)    fmt.Printf("Confidence: %.2f\n", result.Confidence)    // Output:    // Suggested filename: 2024-01-15_AcmeCorp_INV-1234.pdf    // Confidence: 0.95    // Access extracted metadata    fmt.Printf("Vendor: %s\n", result.Metadata.Vendor)    fmt.Printf("Date: %s\n", result.Metadata.Date)    fmt.Printf("Type: %s\n", result.Metadata.Type)    // Use custom naming instructions    customResult, err := client.Rename(ctx, data, renamed.RenameOptions{        Instructions: "Format: YYYY-MM-DD_VendorName_Amount",    })    if err != nil {        log.Fatalf("custom rename failed: %v", err)    }    fmt.Println(customResult.SuggestedFilename)    // -> "2024-01-15_AcmeCorp_$1250.pdf"}

Split a PDF

Split multi-page PDFs into separate documents. The API uses async jobs for large files—poll for completion or use the built-in wait helper.

split.go
Go
package mainimport (    "context"    "fmt"    "log"    "os"    "time"    renamed "github.com/renamed-to/renamed-sdk/sdks/go")func main() {    client := renamed.NewClient(os.Getenv("RENAMED_API_KEY"))    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)    defer cancel()    // Read a multi-page PDF    data, err := os.ReadFile("./documents/combined.pdf")    if err != nil {        log.Fatalf("failed to read file: %v", err)    }    // Submit the split job with smart mode (AI detects document boundaries)    job, err := client.PDFSplit(ctx, data, renamed.SplitOptions{        Mode: "smart",    })    if err != nil {        log.Fatalf("split failed: %v", err)    }    fmt.Printf("Job ID: %s\n", job.JobID)    fmt.Printf("Status: %s\n", job.State)    // Option 1: Wait for completion (built-in polling)    completed, err := job.WaitForCompletion(ctx)    if err != nil {        log.Fatalf("job failed: %v", err)    }    // Option 2: Manual polling for progress updates    // for {    //     status, err := client.GetJob(ctx, job.JobID)    //     if err != nil {    //         log.Fatalf("get job failed: %v", err)    //     }    //     fmt.Printf("Progress: %d%%\n", status.Progress)    //     if status.State == "completed" {    //         completed = status    //         break    //     }    //     time.Sleep(1 * time.Second)    // }    // Process the split documents    fmt.Printf("Split into %d documents:\n", len(completed.Documents))    for i, doc := range completed.Documents {        fmt.Printf("  [%d] %s (pages %v)\n", i+1, doc.Filename, doc.Pages)        // Output:        // [1] invoice_1.pdf (pages [1 2])        // [2] invoice_2.pdf (pages [3 4])        // Download each split document        pdfBytes, err := client.DownloadFile(ctx, doc.DownloadURL)        if err != nil {            log.Printf("download failed for %s: %v", doc.Filename, err)            continue        }        // Save to output directory        outPath := fmt.Sprintf("./output/%s", doc.Filename)        if err := os.WriteFile(outPath, pdfBytes, 0644); err != nil {            log.Printf("write failed for %s: %v", outPath, err)        }    }}

Extract Data

Extract structured data from invoices, receipts, and other documents. Use Go structs for type-safe extraction.

extract.go
Go
package mainimport (    "context"    "encoding/json"    "fmt"    "log"    "os"    "time"    renamed "github.com/renamed-to/renamed-sdk/sdks/go")// Define a typed struct for invoice extractiontype Invoice struct {    InvoiceNumber string     `json:"invoiceNumber"`    Vendor        string     `json:"vendor"`    Date          string     `json:"date"`    LineItems     []LineItem `json:"lineItems"`    Subtotal      float64    `json:"subtotal"`    Tax           float64    `json:"tax"`    Total         float64    `json:"total"`}type LineItem struct {    Description string  `json:"description"`    Quantity    int     `json:"quantity"`    UnitPrice   float64 `json:"unitPrice"`}func main() {    client := renamed.NewClient(os.Getenv("RENAMED_API_KEY"))    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)    defer cancel()    data, err := os.ReadFile("./documents/invoice.pdf")    if err != nil {        log.Fatalf("failed to read file: %v", err)    }    // Basic extraction (returns map[string]interface{})    extracted, err := client.Extract(ctx, data)    if err != nil {        log.Fatalf("extract failed: %v", err)    }    fmt.Printf("Vendor: %v\n", extracted["vendor"])    fmt.Printf("Date: %v\n", extracted["date"])    fmt.Printf("Total: %v\n", extracted["total"])    // Output:    // Vendor: Acme Corp    // Date: 2024-01-15    // Total: 1250.00    // Typed extraction: unmarshal into a struct    jsonBytes, err := json.Marshal(extracted)    if err != nil {        log.Fatalf("marshal failed: %v", err)    }    var invoice Invoice    if err := json.Unmarshal(jsonBytes, &invoice); err != nil {        log.Fatalf("unmarshal failed: %v", err)    }    // Now you have fully typed access    fmt.Printf("Invoice #%s from %s\n", invoice.InvoiceNumber, invoice.Vendor)    fmt.Printf("Line items: %d\n", len(invoice.LineItems))    for _, item := range invoice.LineItems {        fmt.Printf("  - %s: %d x $%.2f\n", item.Description, item.Quantity, item.UnitPrice)    }    fmt.Printf("Total: $%.2f\n", invoice.Total)}

Framework Integrations

Common integration patterns for popular frameworks.

Gin Handler

Handle PDF uploads in a Gin web server with proper error responses and file validation.

main.go
Go
package mainimport (    "net/http"    "os"    "github.com/gin-gonic/gin"    renamed "github.com/renamed-to/renamed-sdk/sdks/go")var client = renamed.NewClient(os.Getenv("RENAMED_API_KEY"))func main() {    r := gin.Default()    // Set a reasonable max upload size (10MB)    r.MaxMultipartMemory = 10 << 20    r.POST("/api/rename", handleRename)    r.POST("/api/extract", handleExtract)    r.Run(":8080")}func handleRename(c *gin.Context) {    // Get the uploaded file    file, err := c.FormFile("file")    if err != nil {        c.JSON(http.StatusBadRequest, gin.H{"error": "No file provided"})        return    }    // Validate file type    if file.Header.Get("Content-Type") != "application/pdf" {        c.JSON(http.StatusBadRequest, gin.H{"error": "Only PDF files are supported"})        return    }    // Open and read the file    f, err := file.Open()    if err != nil {        c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to open file"})        return    }    defer f.Close()    data := make([]byte, file.Size)    if _, err := f.Read(data); err != nil {        c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to read file"})        return    }    // Call the Renamed API    result, err := client.Rename(c.Request.Context(), data)    if err != nil {        c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})        return    }    c.JSON(http.StatusOK, gin.H{        "suggestedFilename": result.SuggestedFilename,        "confidence":        result.Confidence,        "metadata":          result.Metadata,    })}func handleExtract(c *gin.Context) {    file, err := c.FormFile("file")    if err != nil {        c.JSON(http.StatusBadRequest, gin.H{"error": "No file provided"})        return    }    f, err := file.Open()    if err != nil {        c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to open file"})        return    }    defer f.Close()    data := make([]byte, file.Size)    if _, err := f.Read(data); err != nil {        c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to read file"})        return    }    extracted, err := client.Extract(c.Request.Context(), data)    if err != nil {        c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})        return    }    c.JSON(http.StatusOK, extracted)}

Echo Handler

Process PDF uploads with Echo framework using its multipart form handling and context.

main.go
Go
package mainimport (    "io"    "net/http"    "os"    "github.com/labstack/echo/v4"    "github.com/labstack/echo/v4/middleware"    renamed "github.com/renamed-to/renamed-sdk/sdks/go")var client = renamed.NewClient(os.Getenv("RENAMED_API_KEY"))func main() {    e := echo.New()    // Middleware    e.Use(middleware.Logger())    e.Use(middleware.Recover())    // Routes    e.POST("/api/rename", handleRename)    e.POST("/api/split", handleSplit)    e.Logger.Fatal(e.Start(":8080"))}func handleRename(c echo.Context) error {    // Get the uploaded file from multipart form    file, err := c.FormFile("file")    if err != nil {        return c.JSON(http.StatusBadRequest, map[string]string{            "error": "No file provided",        })    }    // Open the file    src, err := file.Open()    if err != nil {        return c.JSON(http.StatusInternalServerError, map[string]string{            "error": "Failed to open file",        })    }    defer src.Close()    // Read file contents    data, err := io.ReadAll(src)    if err != nil {        return c.JSON(http.StatusInternalServerError, map[string]string{            "error": "Failed to read file",        })    }    // Use Echo's request context for cancellation support    result, err := client.Rename(c.Request().Context(), data)    if err != nil {        return c.JSON(http.StatusInternalServerError, map[string]string{            "error": err.Error(),        })    }    return c.JSON(http.StatusOK, map[string]interface{}{        "suggestedFilename": result.SuggestedFilename,        "confidence":        result.Confidence,        "metadata":          result.Metadata,    })}func handleSplit(c echo.Context) error {    file, err := c.FormFile("file")    if err != nil {        return c.JSON(http.StatusBadRequest, map[string]string{            "error": "No file provided",        })    }    src, err := file.Open()    if err != nil {        return c.JSON(http.StatusInternalServerError, map[string]string{            "error": "Failed to open file",        })    }    defer src.Close()    data, err := io.ReadAll(src)    if err != nil {        return c.JSON(http.StatusInternalServerError, map[string]string{            "error": "Failed to read file",        })    }    // Get split mode from query param (default: smart)    mode := c.QueryParam("mode")    if mode == "" {        mode = "smart"    }    job, err := client.PDFSplit(c.Request().Context(), data, renamed.SplitOptions{        Mode: mode,    })    if err != nil {        return c.JSON(http.StatusInternalServerError, map[string]string{            "error": err.Error(),        })    }    // Wait for completion    completed, err := job.WaitForCompletion(c.Request().Context())    if err != nil {        return c.JSON(http.StatusInternalServerError, map[string]string{            "error": err.Error(),        })    }    return c.JSON(http.StatusOK, map[string]interface{}{        "jobId":     completed.JobID,        "documents": completed.Documents,    })}

Error Handling

The SDK returns idiomatic Go errors. Use errors.Is() and errors.As() for specific error types.

errors.go
Go
package mainimport (    "context"    "errors"    "fmt"    "log"    "os"    "time"    renamed "github.com/renamed-to/renamed-sdk/sdks/go")func main() {    client := renamed.NewClient(os.Getenv("RENAMED_API_KEY"))    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)    defer cancel()    data, err := os.ReadFile("invoice.pdf")    if err != nil {        log.Fatalf("failed to read file: %v", err)    }    result, err := client.Rename(ctx, data)    if err != nil {        // Check for rate limiting        var rateLimitErr *renamed.RateLimitError        if errors.As(err, &rateLimitErr) {            fmt.Printf("Rate limited. Retry after %d seconds\n", rateLimitErr.RetryAfter)            return        }        // Check for API errors        var apiErr *renamed.APIError        if errors.As(err, &apiErr) {            fmt.Printf("API Error [%s]: %s\n", apiErr.Code, apiErr.Message)            return        }        // Check for context timeout/cancellation        if errors.Is(err, context.DeadlineExceeded) {            fmt.Println("Request timed out")            return        }        if errors.Is(err, context.Canceled) {            fmt.Println("Request was canceled")            return        }        // Unknown error        log.Fatalf("unexpected error: %v", err)    }    fmt.Printf("Renamed to: %s\n", result.SuggestedFilename)}

Full documentation on GitHub

For more examples, advanced usage patterns, and detailed API documentation, see the full Go SDK README on GitHub.

Read the Go SDK docs

Frequently asked questions

What Go versions are supported?
The Go SDK supports Go 1.21 and above. It uses generics and other modern Go features.
Does the SDK support context cancellation?
Yes, all methods accept a context.Context for cancellation and timeout support.
How do I handle errors?
The SDK returns standard Go errors. Use errors.Is() and errors.As() to check for specific error types like renamed.ErrRateLimited.

Related resources

Other languages