GitHub torrentclaw org is shadow-banned; CI is hosted at git.torrentclaw.com now. Move workflows into the runner's natively-watched .forgejo/workflows/ tree and adapt steps to run in the available 'docker'-labeled Forgejo runner without GitHub-only tooling (gh CLI, third-party marketplace actions). - Use container: image to ship the toolchain (no actions/setup-* needed). - Drop GitHub-only marketplace actions in favour of upstream installers invoked over curl/apt. - Where a workflow created a GitHub Release (release.yml), substitute the step with a curl call against the Forgejo Releases API (POST /repos/<owner>/<repo>/releases). |
||
|---|---|---|
| .forgejo/workflows | ||
| .lefthook/commit-msg | ||
| .gitignore | ||
| CHANGELOG.md | ||
| client.go | ||
| client_test.go | ||
| collections.go | ||
| collections_test.go | ||
| content.go | ||
| content_test.go | ||
| CONTRIBUTING.md | ||
| debrid.go | ||
| debrid_test.go | ||
| doc.go | ||
| errors.go | ||
| errors_test.go | ||
| example_test.go | ||
| go.mod | ||
| health.go | ||
| health_test.go | ||
| lefthook.yml | ||
| LICENSE | ||
| Makefile | ||
| README.md | ||
| search.go | ||
| search_test.go | ||
| stats.go | ||
| stats_test.go | ||
| streaming.go | ||
| streaming_test.go | ||
| torrent.go | ||
| torrent_test.go | ||
| torznab.go | ||
| torznab_test.go | ||
| trending.go | ||
| trending_test.go | ||
| types.go | ||
| upcoming.go | ||
| upcoming_test.go | ||
TorrentClaw Go Client
Go client library for the TorrentClaw API.
About TorrentClaw
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
Links
| Website | torrentclaw.com |
| API Docs (OpenAPI) | torrentclaw.com/api/openapi.json |
| Discord | Coming soon |
| GitHub | github.com/torrentclaw |
Ecosystem
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 |
Features
- 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
Installation
go get github.com/torrentclaw/go-client
Requires Go 1.22 or later.
Quick Start
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 Configuration
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
)
API Reference
Search
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"
})
Autocomplete
suggestions, err := client.Autocomplete(ctx, "incep")
Popular Content
resp, err := client.Popular(ctx, 10, 1) // limit, page (0 = server default)
Recent Content
resp, err := client.Recent(ctx, 12, 1)
Watch Providers
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 countries
Credits
credits, err := client.Credits(ctx, contentID)
// credits.Director — director name
// credits.Cast — top 10 cast members
Stats
stats, err := client.Stats(ctx)
// stats.Content.Movies, stats.Content.Shows
// stats.Torrents.Total, stats.Torrents.BySource
// stats.RecentIngestions
Torrent File
// Get the download URL (no HTTP call)
url := client.TorrentDownloadURL("abc123...")
// Download the .torrent file
data, err := client.GetTorrentFile(ctx, "abc123...")
Error Handling
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))
Development
# 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 all
See CONTRIBUTING.md for full setup instructions including lefthook installation.
Contributing
Contributions are welcome! Please read our Contributing Guide before submitting a pull request.
Reporting Bugs
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
Requesting Features
Have an idea? Open a feature request on GitHub. We'd love to hear from you.
License
Made with ❤️ by the TorrentClaw community
Website · GitHub