Go client library for the TorrentClaw API.
TorrentClaw is a torrent search engine that aggregates movies and TV shows from 30+ international sources into a single, clean API. No ads, no tracking.
- Quality scoring — torrents ranked by real quality metrics, not just seeders
- TMDB metadata — posters, ratings, genres, cast, and crew for every result
- Watch providers — see where content is streaming (Netflix, Amazon, Disney+, etc.)
- Semantic search — natural language queries in 11+ languages
- TrueSpec verification — verify actual media specs from info hashes
| Website | torrentclaw.com |
| API Docs (OpenAPI) | torrentclaw.com/api/openapi.json |
| Discord | Coming soon |
| GitHub | github.com/torrentclaw |
TorrentClaw is more than just an API. It's a growing ecosystem of tools:
| Project | Language | Description |
|---|---|---|
| torrentclaw-go-client | Go | API client library (this repo) |
| torrentclaw-cli | Go | Command-line interface (coming soon) |
| torrentclaw-mcp | TypeScript | MCP server for AI agents |
| truespec | Go | Verify real media specs from info hashes |
| torrentclaw-skill | - | Agent skill for OpenClaw |
- Zero external dependencies — stdlib only
- Context support on all methods
- Functional options for client configuration
- Exponential backoff retry for transient errors (429, 5xx)
- Custom error types with helper methods (
IsRetryable,IsRateLimited,IsNotFound) - Full API coverage — search, autocomplete, popular, recent, watch providers, credits, stats, torrent download
go get github.com/torrentclaw/go-clientRequires Go 1.22 or later.
package main
import (
"context"
"fmt"
"log"
torrentclaw "github.com/torrentclaw/go-client"
)
func main() {
client := torrentclaw.NewClient(
torrentclaw.WithAPIKey("your-api-key"),
)
resp, err := client.Search(context.Background(), torrentclaw.SearchParams{
Query: "Inception",
Type: "movie",
Quality: "1080p",
Sort: "seeders",
})
if err != nil {
log.Fatal(err)
}
for _, result := range resp.Results {
fmt.Printf("%s (%d)\n", result.Title, *result.Year)
for _, t := range result.Torrents {
fmt.Printf(" %s — %d seeders\n", t.InfoHash, t.Seeders)
}
}
}client := torrentclaw.NewClient(
torrentclaw.WithAPIKey("your-api-key"), // API key (X-API-Key header)
torrentclaw.WithBaseURL("https://custom.example"), // Custom base URL
torrentclaw.WithTimeout(30 * time.Second), // HTTP timeout (default: 15s)
torrentclaw.WithUserAgent("my-app/1.0"), // Custom User-Agent
torrentclaw.WithHTTPClient(customHTTPClient), // Custom *http.Client
torrentclaw.WithRetry(5, 2*time.Second, 60*time.Second), // Retry policy
)resp, err := client.Search(ctx, torrentclaw.SearchParams{
Query: "Breaking Bad",
Type: "show", // "movie" or "show"
Genre: "Drama", // exact genre match
YearMin: 2008,
YearMax: 2013,
MinRating: 8.0, // 0-10
Quality: "1080p", // "480p", "720p", "1080p", "2160p"
Language: "en", // ISO 639 code
Audio: "atmos", // audio codec substring
HDR: "dolby_vision", // HDR format
Sort: "seeders", // "relevance", "seeders", "year", "rating", "added"
Page: 1,
Limit: 20,
Country: "US", // includes streaming availability
Locale: "es", // localized titles/overviews
Availability: "available", // "all", "available", "unavailable"
})suggestions, err := client.Autocomplete(ctx, "incep")resp, err := client.Popular(ctx, 10, 1) // limit, page (0 = server default)resp, err := client.Recent(ctx, 12, 1)resp, err := client.WatchProviders(ctx, contentID, "US")
// resp.Providers.Flatrate — subscription (Netflix, Disney+, etc.)
// resp.Providers.Rent — available for rental
// resp.Providers.Buy — available for purchase
// resp.Providers.Free — free with ads
// resp.VPNSuggestion — available in other countriescredits, err := client.Credits(ctx, contentID)
// credits.Director — director name
// credits.Cast — top 10 cast membersstats, err := client.Stats(ctx)
// stats.Content.Movies, stats.Content.Shows
// stats.Torrents.Total, stats.Torrents.BySource
// stats.RecentIngestions// Get the download URL (no HTTP call)
url := client.TorrentDownloadURL("abc123...")
// Download the .torrent file
data, err := client.GetTorrentFile(ctx, "abc123...")All API errors are returned as *torrentclaw.APIError:
resp, err := client.Search(ctx, params)
if err != nil {
var apiErr *torrentclaw.APIError
if errors.As(err, &apiErr) {
fmt.Printf("HTTP %d: %s\n", apiErr.StatusCode, apiErr.Message)
if apiErr.IsRateLimited() {
// Handle 429
}
if apiErr.IsNotFound() {
// Handle 404
}
if apiErr.IsRetryable() {
// 429, 500, 502, 503 — retries are automatic by default
}
}
}Transient errors (429, 500, 502, 503) are automatically retried with exponential backoff. Configure the retry policy with WithRetry:
// Disable retries
client := torrentclaw.NewClient(torrentclaw.WithRetry(0, 0, 0))
// Custom: 5 retries, starting at 2s, capped at 60s
client := torrentclaw.NewClient(torrentclaw.WithRetry(5, 2*time.Second, 60*time.Second))# Install git hooks (requires lefthook)
make install-hooks
# Run tests
make test
# Run linter
make lint
# Run tests with coverage
make coverage
# Format code
make fmt
# Check formatting (CI-friendly, no write)
make check
# Run all checks
make allSee CONTRIBUTING.md for full setup instructions including lefthook installation.
Contributions are welcome! Please read our Contributing Guide before submitting a pull request.
Found a bug? Open an issue on GitHub with:
- A clear description of the problem
- Steps to reproduce
- Expected vs actual behavior
- Go version and OS
Have an idea? Open a feature request on GitHub. We'd love to hear from you.
Made with ❤️ by the TorrentClaw community
Website · GitHub