{"id":34632632,"url":"https://github.com/ujeebu/ujeebu-go","last_synced_at":"2026-01-13T20:37:22.884Z","repository":{"id":330305973,"uuid":"970942447","full_name":"ujeebu/ujeebu-go","owner":"ujeebu","description":"Go SDK for the Ujeebu web scraping and content extraction API with full context support, structured error handling","archived":false,"fork":false,"pushed_at":"2025-12-24T14:41:58.000Z","size":62,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-12-26T05:44:45.829Z","etag":null,"topics":["data-extraction","scraping","sdk-go","serp"],"latest_commit_sha":null,"homepage":"https://ujeebu.com/docs","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ujeebu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-04-22T19:12:40.000Z","updated_at":"2025-12-24T14:42:01.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ujeebu/ujeebu-go","commit_stats":null,"previous_names":["ujeebu/ujeebu-go"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/ujeebu/ujeebu-go","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ujeebu%2Fujeebu-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ujeebu%2Fujeebu-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ujeebu%2Fujeebu-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ujeebu%2Fujeebu-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ujeebu","download_url":"https://codeload.github.com/ujeebu/ujeebu-go/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ujeebu%2Fujeebu-go/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28399855,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-13T14:36:09.778Z","status":"ssl_error","status_checked_at":"2026-01-13T14:35:19.697Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["data-extraction","scraping","sdk-go","serp"],"created_at":"2025-12-24T16:53:49.680Z","updated_at":"2026-01-13T20:37:22.872Z","avatar_url":"https://github.com/ujeebu.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ujeebu API Go SDK\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/ujeebu/ujeebu-go.svg)](https://pkg.go.dev/github.com/ujeebu/ujeebu-go)\n[![Go Report Card](https://goreportcard.com/badge/github.com/ujeebu/ujeebu-go)](https://goreportcard.com/report/github.com/ujeebu/ujeebu-go)\n\n[Ujeebu](https://ujeebu.com) is a comprehensive API platform for web scraping, content extraction, and search engine results. This SDK provides a robust, production-ready interface for Go applications with support for:\n\n- 🔄 **Context-based cancellation** - Full support for context.Context in all API calls\n- ⚡ **Options pattern** - Flexible client configuration\n- 🛡️ **Strong error handling** - Structured error types with helper methods\n- 📊 **Credit tracking** - Monitor API usage in real-time\n- 🧪 **Comprehensive testing** - Well-tested with extensive unit test coverage\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Client Configuration](#client-configuration)\n- [API Endpoints](#api-endpoints)\n  - [Extract API](#extract-api)\n  - [Card API](#card-api)\n  - [Scrape API](#scrape-api)\n  - [SERP API](#serp-api)\n  - [Account API](#account-api)\n- [Advanced Usage](#advanced-usage)\n  - [Context Support](#context-support)\n  - [Error Handling](#error-handling)\n  - [Custom Headers](#custom-headers)\n  - [Proxy Support](#proxy-support)\n  - [Retry Configuration](#retry-configuration)\n- [Examples](#examples)\n- [Testing](#testing)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Installation\n\n```bash\ngo get github.com/ujeebu/ujeebu-go\n```\n\n## Quick Start\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/ujeebu/ujeebu-go\"\n)\n\nfunc main() {\n\t// Create a new client with your API key\n\tclient, err := ujeebu.NewClient(\"YOUR-API-KEY\")\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create client: %v\", err)\n\t}\n\n\t// Extract article content\n\tparams := ujeebu.ExtractParams{\n\t\tURL: \"https://ujeebu.com/blog/web-scraping-in-2025-state-of-the-art-and-trends/\",\n\t}\n\n\tarticle, credits, err := client.Extract(params)\n\tif err != nil {\n\t\tlog.Fatalf(\"Extraction failed: %v\", err)\n\t}\n\n\tfmt.Printf(\"Title: %s\\n\", article.Title)\n\tfmt.Printf(\"Author: %s\\n\", article.Author)\n\tfmt.Printf(\"Credits used: %d\\n\", credits)\n}\n```\n\n## Client Configuration\n\nThe SDK uses an options pattern for flexible client configuration:\n\n```go\nimport (\n\t\"time\"\n\t\"github.com/ujeebu/ujeebu-go\"\n)\n\nclient, err := ujeebu.NewClient(\n\t\"YOUR-API-KEY\",\n\tujeebu.WithTimeout(120 * time.Second),              // Custom timeout\n\tujeebu.WithBaseURL(\"https://custom.api.url\"),       // Custom API URL\n\tujeebu.WithDebug(true),                             // Enable debug logging\n\tujeebu.WithUserAgent(\"MyApp/1.0\"),                  // Custom user agent\n\tujeebu.WithRetry(3, time.Second, 5*time.Second),    // Retry configuration\n)\nif err != nil {\n\tlog.Fatalf(\"Failed to create client: %v\", err)\n}\n```\n\n### Available Options\n\n- `WithTimeout(duration)` - Set custom HTTP client timeout (default: 90 seconds)\n- `WithBaseURL(url)` - Set custom API base URL (default: https://api.ujeebu.com)\n- `WithDebug(bool)` - Enable/disable debug mode with detailed logging\n- `WithLogger(logger)` - Set custom logger implementing the Logger interface\n- `WithUserAgent(ua)` - Set custom User-Agent header\n- `WithRetry(maxRetries, waitTime, maxWaitTime)` - Configure retry behavior\n\n### Environment Variables\n\n- `UJEEBU_BASE_URL` - Override the default API base URL\n\n## API Endpoints\n\n### Extract API\n\nThe Extract API automatically extracts clean, structured content from web pages.\n\n#### Basic Usage\n\n```go\nparams := ujeebu.ExtractParams{\n\tURL: \"https://example.com/article\",\n}\n\narticle, credits, err := client.Extract(params)\nif err != nil {\n\tlog.Fatalf(\"Extraction failed: %v\", err)\n}\n\nfmt.Printf(\"Title: %s\\n\", article.Title)\nfmt.Printf(\"Text: %s\\n\", article.Text)\nfmt.Printf(\"Author: %s\\n\", article.Author)\nfmt.Printf(\"Publication Date: %s\\n\", article.PubDate)\n```\n\n#### Advanced Options\n\n```go\nparams := ujeebu.ExtractParams{\n\tURL:           \"https://example.com/article\",\n\tJS:            true,                    // Enable JavaScript rendering\n\tJSTimeout:     10000,                   // JS execution timeout (ms)\n\tText:          true,                    // Extract text content\n\tHTML:          true,                    // Include HTML\n\tImages:        true,                    // Extract images\n\tAuthor:        true,                    // Extract author information\n\tPubDate:       true,                    // Extract publication date\n\tPagination:    true,                    // Handle multi-page articles\n\tPaginationMaxPages: 5,                  // Maximum pages to extract\n\tProxyType:     \"premium\",               // Use premium proxies\n\tProxyCountry:  \"us\",                    // Proxy location\n\tSessionID:     \"my-session-123\",        // Session for cookie persistence\n\tCustomHeaders: map[string]string{       // Custom headers (prefixed with UJB-)\n\t\t\"Authorization\": \"Bearer token\",\n\t},\n}\n\narticle, credits, err := client.Extract(params)\n```\n\n#### Extract from Raw HTML\n\n```go\nparams := ujeebu.ExtractParams{\n\tURL:    \"https://example.com/article\",\n\tRawHTML: \"\u003chtml\u003e\u003cbody\u003e\u003ch1\u003eTitle\u003c/h1\u003e\u003cp\u003eContent\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e\",\n}\n\narticle, credits, err := client.Extract(params)\n```\n\n### Card API\n\nThe Card API quickly retrieves metadata and preview information from URLs, optimized for social media cards and link previews.\n\n#### Basic Usage\n\n```go\nparams := ujeebu.CardParams{\n\tURL: \"https://example.com/article\",\n}\n\ncard, credits, err := client.Card(params)\nif err != nil {\n\tlog.Fatalf(\"Card fetch failed: %v\", err)\n}\n\nfmt.Printf(\"Title: %s\\n\", card.Title)\nfmt.Printf(\"Summary: %s\\n\", card.Summary)\nfmt.Printf(\"Image: %s\\n\", card.Image)\nfmt.Printf(\"Favicon: %s\\n\", card.Favicon)\nfmt.Printf(\"Site Name: %s\\n\", card.SiteName)\n```\n\n#### Advanced Options\n\n```go\nparams := ujeebu.CardParams{\n\tURL:          \"https://example.com\",\n\tJS:           true,                    // Enable JavaScript for SPAs\n\tJSTimeout:    5000,                    // JS timeout (ms)\n\tTimeout:      30,                      // Request timeout (seconds)\n\tProxyType:    \"datacenter\",            // Proxy type\n\tProxyCountry: \"us\",                    // Proxy country\n\tCustomProxy:  \"http://proxy:8080\",    // Custom proxy URL\n\tAutoProxy:    true,                    // Automatic proxy selection\n\tSessionID:    \"session-123\",           // Session ID for cookies\n\tCustomHeaders: map[string]string{      // Custom headers\n\t\t\"Accept-Language\": \"en-US\",\n\t},\n}\n\ncard, credits, err := client.Card(params)\n```\n\n### Scrape API\n\nThe Scrape API provides full control over web page scraping with JavaScript rendering, screenshots, PDFs, and custom extraction rules.\n\n#### Basic Scraping\n\n```go\nparams := ujeebu.ScrapeParams{\n\tURL: \"https://example.com\",\n}\n\nresponse, credits, err := client.Scrape(params)\nif err != nil {\n\tlog.Fatalf(\"Scraping failed: %v\", err)\n}\n\nfmt.Printf(\"Success: %v\\n\", response.Success)\nfmt.Printf(\"HTML: %s\\n\", response.HTML)\nfmt.Printf(\"Status Code: %d\\n\", response.StatusCode)\nfmt.Printf(\"Content-Type: %s\\n\", response.ResponseHeaders.Get(\"Content-Type\"))\n```\n\n#### Screenshot Capture\n\n```go\nparams := ujeebu.ScrapeParams{\n\tURL: \"https://example.com\",\n}\n\n// Full page screenshot\nscreenshot, credits, err := client.Screenshot(params, true, \"\")\n\n// Partial screenshot with CSS selector\nscreenshot, credits, err := client.Screenshot(params, false, \".main-content\")\n```\n\n#### PDF Generation\n\n```go\nparams := ujeebu.ScrapeParams{\n\tURL: \"https://example.com\",\n}\n\npdf, credits, err := client.PDF(params)\n```\n\n#### Advanced Scraping with JavaScript\n\n```go\nparams := ujeebu.ScrapeParams{\n\tURL:            \"https://example.com\",\n\tJS:             true,                     // Enable JavaScript\n\tJSTimeout:      15000,                    // JS execution timeout\n\tWaitFor:        \".products-loaded\",       // Wait for element\n\tWaitForTimeout: 10000,                    // Wait timeout\n\tScrollDown:     true,                     // Auto-scroll\n\tScrollWait:     2000,                     // Wait between scrolls\n\tProgressiveScroll: true,                  // Progressive scrolling\n\tCustomJS:       \"document.body.click()\",  // Custom JavaScript\n\tDevice:         \"mobile\",                 // Device type\n\tWindowWidth:    375,                      // Window width\n\tWindowHeight:   667,                      // Window height\n\tBlockAds:       true,                     // Block advertisements\n\tBlockResources: true,                     // Block images/fonts/etc\n\tProxyType:      \"premium\",                // Premium proxies\n\tProxyCountry:   \"us\",                     // Proxy location\n\tCustomHeaders: map[string]string{         // Custom headers\n\t\t\"Accept-Language\": \"en-US\",\n\t},\n}\n\nresponse, credits, err := client.Scrape(params)\n```\n\n#### Extraction Rules\n\n```go\nparams := ujeebu.ScrapeParams{\n\tURL: \"https://example.com/products\",\n\tExtractRules: map[string]any{\n\t\t\"products\": map[string]any{\n\t\t\t\"_selector\": \".product\",\n\t\t\t\"title\":     \".product-title\",\n\t\t\t\"price\":     \".product-price\",\n\t\t\t\"image\":     map[string]string{\n\t\t\t\t\"_selector\":  \".product-image\",\n\t\t\t\t\"_attribute\": \"src\",\n\t\t\t},\n\t\t},\n\t},\n}\n\nresponse, credits, err := client.Scrape(params)\n// Access extracted data via response.Result\n```\n\n### SERP API\n\nThe SERP (Search Engine Results Page) API provides Google search results in structured format.\n\n#### Google Web Search\n\n```go\nparams := ujeebu.SerpParams{\n\tSearch:       \"golang web scraping\",\n\tSearchType:   \"text\",                    // Optional: defaults to text\n\tLang:         \"en\",                      // Language\n\tLocation:     \"us\",                      // Location\n\tDevice:       \"desktop\",                 // Device type\n\tResultsCount: 10,                        // Results per page\n\tPage:         1,                         // Page number\n}\n\nresults, credits, err := client.GoogleSearch(params)\nif err != nil {\n\tlog.Fatalf(\"Search failed: %v\", err)\n}\n\n// Access organic results\nfor _, result := range results.OrganicResults {\n\tfmt.Printf(\"Title: %s\\n\", result.Title)\n\tfmt.Printf(\"Link: %s\\n\", result.Link)\n\tfmt.Printf(\"Description: %s\\n\", result.Description)\n}\n\n// Access knowledge graph\nif results.KnowledgeGraph.Title != \"\" {\n\tfmt.Printf(\"Knowledge Graph: %s\\n\", results.KnowledgeGraph.Title)\n}\n```\n\n#### Google News Search\n\n```go\nparams := ujeebu.SerpParams{\n\tSearch:   \"tech news\",\n\tLocation: \"us\",\n\tLang:     \"en\",\n}\n\nresults, credits, err := client.GoogleNewsSearch(params)\nfor _, news := range results.News {\n\tfmt.Printf(\"Title: %s\\n\", news.Title)\n\tfmt.Printf(\"Source: %s\\n\", news.SiteName)\n\tfmt.Printf(\"Date: %s\\n\", news.Date)\n\tfmt.Printf(\"Link: %s\\n\", news.Link)\n}\n```\n\n#### Google Video Search\n\n```go\nparams := ujeebu.SerpParams{\n\tSearch: \"golang tutorial\",\n\tLang:   \"en\",\n}\n\nresults, credits, err := client.GoogleVideoSearch(params)\nfor _, video := range results.Videos {\n\tfmt.Printf(\"Title: %s\\n\", video.Title)\n\tfmt.Printf(\"Provider: %s\\n\", video.Provider)\n\tfmt.Printf(\"URL: %s\\n\", video.Url)\n}\n```\n\n#### Google Image Search\n\n```go\nparams := ujeebu.SerpParams{\n\tSearch: \"golang logo\",\n\tLang:   \"en\",\n}\n\nresults, credits, err := client.GoogleImageSearch(params)\nfor _, image := range results.Images {\n\tfmt.Printf(\"Title: %s\\n\", image.Title)\n\tfmt.Printf(\"Source: %s\\n\", image.Source)\n\tfmt.Printf(\"Image URL: %s\\n\", image.Image)\n\tfmt.Printf(\"Size: %dx%d\\n\", image.Width, image.Height)\n}\n```\n\n#### Google Maps Search\n\n```go\nparams := ujeebu.SerpParams{\n\tSearch:   \"restaurants near me\",\n\tLocation: \"us\",\n\tLang:     \"en\",\n}\n\nresults, credits, err := client.GoogleMapSearch(params)\nfor _, place := range results.Maps {\n\tfmt.Printf(\"Name: %s\\n\", place.Title)\n\tfmt.Printf(\"Address: %s\\n\", place.Address)\n\tfmt.Printf(\"Rating: %.1f (%d reviews)\\n\", place.Rating, place.Reviews)\n\tfmt.Printf(\"Category: %s\\n\", place.Category)\n}\n```\n\n### Account API\n\nCheck your account usage and billing information.\n\n```go\naccount, err := client.Account()\nif err != nil {\n\tlog.Fatalf(\"Failed to get account info: %v\", err)\n}\n\nfmt.Printf(\"Plan: %s\\n\", account.Plan)\nfmt.Printf(\"Quota: %s\\n\", account.Quota)\nfmt.Printf(\"Used: %d (%.1f%%)\\n\", account.Used, account.UsedPercent)\nfmt.Printf(\"Balance: %d credits\\n\", account.Balance)\nfmt.Printf(\"Concurrent Requests: %d\\n\", account.ConcurrentRequests)\n\nif account.NextBillingDate != nil {\n\tfmt.Printf(\"Next Billing: %s\\n\", *account.NextBillingDate)\n\tfmt.Printf(\"Days until billing: %d\\n\", account.DaysTillNextBilling)\n}\n```\n\n## Advanced Usage\n\n### Context Support\n\nAll API methods support context for cancellation and timeouts:\n\n```go\nimport \"context\"\n\n// Create a context with timeout\nctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)\ndefer cancel()\n\n// Use context with API calls\narticle, credits, err := client.ExtractWithContext(ctx, params)\nif err != nil {\n\t// Handle timeout or cancellation\n\tif ctx.Err() == context.DeadlineExceeded {\n\t\tlog.Println(\"Request timed out\")\n\t}\n}\n```\n\nAll endpoints have WithContext variants:\n- `ExtractWithContext(ctx, params)`\n- `CardWithContext(ctx, params)`\n- `ScrapeWithContext(ctx, params)`\n- `SerpWithContext(ctx, params)`\n- `AccountWithContext(ctx)`\n\n### Error Handling\n\nThe SDK provides structured error types for better error handling:\n\n```go\narticle, credits, err := client.Extract(params)\nif err != nil {\n\t// Check error type\n\tvar apiErr *ujeebu.APIError\n\tvar validationErr *ujeebu.ValidationError\n\tvar netErr *ujeebu.NetworkError\n\n\tswitch {\n\tcase errors.As(err, \u0026apiErr):\n\t\t// API error with status code and message\n\t\tfmt.Printf(\"API Error: %s (status: %d)\\n\", apiErr.Message, apiErr.StatusCode)\n\n\t\t// Use helper methods\n\t\tif apiErr.IsUnauthorized() {\n\t\t\tlog.Println(\"Invalid API key\")\n\t\t}\n\t\tif apiErr.IsNotFound() {\n\t\t\tlog.Println(\"Resource not found\")\n\t\t}\n\t\tif apiErr.IsRateLimited() {\n\t\t\tlog.Println(\"Rate limit exceeded\")\n\t\t}\n\t\tif apiErr.IsTimeout() {\n\t\t\tlog.Println(\"Request timed out\")\n\t\t}\n\n\tcase errors.As(err, \u0026validationErr):\n\t\t// Validation error (client-side)\n\t\tfmt.Printf(\"Validation error for %s: %s\\n\", validationErr.Field, validationErr.Message)\n\n\tcase errors.As(err, \u0026netErr):\n\t\t// Network error (connection issues, timeouts)\n\t\tfmt.Printf(\"Network error: %v\\n\", netErr.Err)\n\t}\n}\n```\n\n### Custom Headers\n\nAdd custom headers to requests (they will be prefixed with `UJB-`):\n\n```go\nparams := ujeebu.ExtractParams{\n\tURL: \"https://example.com\",\n\tCustomHeaders: map[string]string{\n\t\t\"Authorization\": \"Bearer token\",\n\t\t\"X-Custom-ID\":   \"12345\",\n\t},\n}\n\n// Headers sent to Ujeebu API:\n// UJB-Authorization: Bearer token\n// UJB-X-Custom-ID: 12345\n```\n\n### Proxy Support\n\nThe SDK supports various proxy types:\n\n```go\nparams := ujeebu.ScrapeParams{\n\tURL:          \"https://example.com\",\n\tProxyType:    \"premium\",           // premium, datacenter, residential\n\tProxyCountry: \"us\",                // Proxy country code\n\tCustomProxy:  \"http://user:pass@proxy.example.com:8080\", // Custom proxy\n\tAutoProxy:    true,                // Automatic proxy selection\n}\n```\n\n### Retry Configuration\n\nConfigure automatic retries for failed requests:\n\n```go\nclient, err := ujeebu.NewClient(\n\t\"YOUR-API-KEY\",\n\tujeebu.WithRetry(\n\t\t3,                      // Max retries\n\t\t1*time.Second,          // Initial wait time\n\t\t10*time.Second,         // Max wait time\n\t),\n)\n```\n\n## Examples\n\nComplete examples are available in the `examples/` directory:\n\n- [Extract Article](examples/extract/main.go) - Basic article extraction\n- [Card Preview](examples/card/main.go) - Get page metadata\n- [Scrape with JavaScript](examples/scrape/main.go) - JavaScript rendering and scrolling\n- [Screenshot](examples/screenshot/main.go) - Capture page screenshots\n- [PDF Generation](examples/pdf/main.go) - Generate PDFs\n- [Google Search](examples/serp/main.go) - Search Google and parse results\n- [Account Info](examples/account/main.go) - Check account usage\n\n## Testing\n\nThe SDK includes comprehensive unit tests with \u003e90% coverage:\n\n```bash\n# Run all tests\ngo test ./...\n\n# Run tests with coverage\ngo test -cover ./...\n\n# Run tests with verbose output\ngo test -v ./...\n\n# Run specific test\ngo test -run TestCard_Success\n```\n\n## Error Reference\n\n### APIError\n\nServer-side errors from the Ujeebu API:\n- **StatusCode**: HTTP status code\n- **Message**: Error message\n- **ErrorCode**: API error code\n- **URL**: Request URL\n\nHelper methods:\n- `IsUnauthorized()` - 401 status code\n- `IsNotFound()` - 404 status code\n- `IsRateLimited()` - 429 status code\n- `IsTimeout()` - 408 or 504 status code\n\n### ValidationError\n\nClient-side validation errors:\n- **Field**: Field name that failed validation\n- **Message**: Validation error message\n\n### NetworkError\n\nNetwork-level errors:\n- **Err**: Underlying error (timeout, connection refused, etc.)\n\n## Best Practices\n\n1. **Always check errors**: Handle errors appropriately for production use\n2. **Use contexts**: Implement timeouts and cancellation for long-running requests\n3. **Monitor credits**: Track credit usage via the returned credits value\n4. **Reuse clients**: Create one client instance and reuse it across requests\n5. **Handle rate limits**: Implement exponential backoff for rate-limited requests\n6. **Set appropriate timeouts**: Adjust timeouts based on your use case\n7. **Use sessions**: For multi-request workflows, use SessionID for cookie persistence\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## Support\n\n- 📧 Email: support@ujeebu.com\n- 📚 Documentation: https://ujeebu.com/docs\n- 🐛 Issues: https://github.com/ujeebu/ujeebu-go/issues\n\n## License\n\nThis SDK is distributed under the MIT License. See LICENSE file for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fujeebu%2Fujeebu-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fujeebu%2Fujeebu-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fujeebu%2Fujeebu-go/lists"}