leadtext
leadtext
leadtext
Invoices, receipts, statements
Auto-title papers
Matter-ready naming
Field, onboarding, reporting ops
Shot logs, call sheets, deliverables
Configs, audit logs, incidents
Transcripts, lesson plans, records
Invoices, product sheets, shipping
Leases, inspections, work orders
Receipts, reports, reimbursements
BOLs, PODs, carrier invoices
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.