Official SDK
Go
Idiomatic Go with context support and proper error handling. Designed for production use with automatic retries and clean interfaces.
Rename PDFs, split multi-page documents, and extract structured data using the official Go SDK for Renamed.to.
- 1Run go get github.com/renamed-to/renamed-sdk/sdks/go to install
- 2Pass context.Context to Rename(), PDFSplit(), or Extract() with PDF bytes
- 3Receive strongly-typed results with idiomatic Go error handling
MIT licensed, open source on GitHub, published on Go Modules.
On this page
Installation
go get github.com/renamed-to/renamed-sdk/sdks/goQuickstart
Initialize the client and start making API calls.
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.
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.
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.
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.
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.
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.
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 docsFrequently 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.