Guide
1. Komma igång
AniRena är ett torrentindex fokuserat på anime, manga, ljud och relaterade medier. Du kan bläddra och ladda ned torrents utan ett konto. Ett konto krävs för att ladda upp torrents, posta i grupper eller använda API:et.
Navigationsraden längst upp ger åtkomst till webbplatsens huvudområden:
- Hem — torrentlistnings- och söksidan.
- Ladda upp — skicka in en ny torrent (kräver inloggning).
- Guide — den här sidan.
- Statistik — webbplatsövergripande statistik (torrents, peers, uppladdningar över tid).
- Grupper — katalog över utgivningsgrupper.
- RSS — RSS-flöde med senaste uppladdningar, filtrerbart efter kategori.
Din kontomeny (övre högra hörnet när du är inloggad) öppnar en profilpanel där du kan justera inställningar, hantera säkerhetsalternativ och komma åt din API-nyckel.
2. Bläddra och sök
Startsidan listar alla torrents sorterade efter uppladdningsdatum. Använd sökfältet längst upp för att filtrera resultat.
Grundläggande sökning
Skriv ord i sökfältet och tryck Enter (eller klicka på sökikonen). Resultat rankas efter relevans när en sökning är aktiv.
Sökoperatorer
Följande operatorer kan kombineras med en vanlig sökning:
| Operator | Exempel | Effekt |
|---|---|---|
user:"name" | user:"SubsPlease" | Visa bara torrents uppladdade av den användaren. |
Klicka på ett uplodarnamn i torrentlistan kör automatiskt en användarsökning.
Kategorier och underkategorier
Använd kategoriväljaren (rutnätikonen bredvid sökfältet) för att begränsa resultat till en kategori. Tillgängliga kategorier:
- Anime
- Manga/Manhwa/Serietidning
- Ljud
- Litteratur
- Live Action
- Bilder
- Programvara
- Hentai
- Övrigt
Varje kategori har underkategorier (t.ex. Anime till RAW, Sub/Ljud, Musikvideo) valbara inuti kategoridialogen.
Sortering och filter
Kolumnrubrikerna i torrentlistan är klickbara för att sortera efter den kolumnen (stigande eller fallande). Tillgängliga sorteringskolumner: datum, namn, storlek, slutförda nedladdningar. Obs: seeders och leechers är livevärden från Redis och kan inte användas för sortering.
Språkfilter
Använd språkväljaren (flaggikon) för att bara visa torrents märkta med ett specifikt språk.
RSS-flöde
RSS-flödet på /rss innehåller de senaste uppladdningarna. Lägg till ?category=anime (eller annan kategori-slug) för att filtrera flödet. De flesta torrent-klienter stöder RSS-automatisk nedladdning direkt från denna URL.
3. Ladda ned torrents
Klicka på ett torrentnamn för att öppna detaljpanelen. Därifrån kan du:
- Ladda ned .torrent — sparar .torrent-filen direkt. Den direkta URL:en är
/torrents/{id}.torrent - Magnetlänk — öppnas direkt i din torrent-klient via magnet-URI-protokollet. URL:en är
/torrents/{id}/magnet
Detaljpanelen visar också torrentbeskrivningen, fillistan, trackerlistan och seeder-/leecherantal.
Äldre nedladdningslänkar
Gamla AniRena-nedladdningslänkar stöds fortfarande och omdirigerar automatiskt till rätt .torrent-fil med hjälp av det äldre ID:t: /dl/{old_id}
Rekommenderade BitTorrent-klienter
Vilken modern BitTorrent-klient som helst fungerar. Klienterna nedan rekommenderas och stöder fullt ut BitTorrent v2 / hybridtorrents:
4. Skapa ett konto
Registrering
Klicka på Registrera dig i navigationsraden. Välj ett användarnamn, ange en e-postadress och ange ett lösenord (minimilängd krävs). Du måste läsa och acceptera webbplatsens villkor innan ditt konto skapas.
E-postaktivering
Efter registrering skickas ett verifieringsmejl till din adress. Klicka på länken i mejlet för att aktivera ditt konto. Om du inte fick det, använd länken Aktivera ditt konto på inloggningssidan för att begära en ny kod.
Lösenordsåterställning
Om du glömmer ditt lösenord klickar du på Glömt lösenord på inloggningssidan och anger din e-postadress. En återställningslänk skickas till dig. Länken är engångsbruk och löper ut efter kort tid.
5. Ladda upp torrents
Navigera till Ladda upp i navigationsraden. Du måste vara inloggad med ett aktivt, icke-avstängt konto. Uppladdningssidan har två flikar:
Uppladdningsflik — skicka in en befintlig .torrent-fil
Dra och släpp eller välj en .torrent-fil. När den är laddad fyller du i fälten:
| Fält | Krävs | Beskrivning |
|---|---|---|
| Torrent-fil | Ja | .torrent-filen som ska laddas upp. |
| Namn | Nej | Åsidosätt torrentens visningsnamn. Om det lämnas tomt används det namn som är inbäddat i torrent-filen. |
| Kategori | Ja | Innehållskategori (Anime, Manga, Ljud, etc.). |
| Underkategori | Nej | En mer specifik typ inom kategorin (t.ex. RAW, Sub/Ljud). |
| Språk | Nej | En eller flera språktaggar som beskriver innehållets språk. |
| Grupp | Nej | Associera den här utgåvan med en grupp du är medlem i. |
| Beskrivning | Nej | Markdown-formaterad beskrivning visad på torrentdetaljsidan (max 65535 tecken). |
| Privat | Nej | Sätter privatflaggan i torrenten, inaktiverar DHT/PEX. Användbart för tracker-only torrents. |
| Annonseringsadress | Nej | Åsidosätt eller lägg till den primära tracker announce URL. |
| Extra trackers | Nej | Läses från torrentfilen. Kan inte ändras vid uppladdning — använd fliken Skapa om du vill anpassa trackerlistan. |
| Kommentar | Nej | Åsidosätt torrentkommentarfältet inbäddat i filen. |
Din torrent måste innehålla minst en AniRena tracker-URL i sin announce-lista (i vilket tier som helst). Sidan kontrollerar detta vid uppladdning och avvisar torrents som inte inkluderar en AniRena tracker. Om du skapade torrenten utan att lägga till AniRena trackern först, ladda upp den och ladda sedan ner den igen från webbplatsen — den nedladdade filen kommer automatiskt att ha rätt trackrar.
Skapaflik — bygg en ny torrent
Skapaflikar låter dig generera en ny .torrent från grunden genom att ange filsökvägar, tracker-URL:er och andra torrentparametrar direkt i webbläsaren. Den resulterande torrenten skickas in med samma metadatafält som ovan.
Moderering
Uppladdningar kontrolleras automatiskt mot en lista med förbjudna innehållsmönster (namn, filnamn, beskrivningar). Torrents som matchar ett förbjudet mönster avvisas. Duplikattorrents (samma info-hash) avvisas också.
6. Ditt konto
Klicka på ditt användarnamn i det övre högra hörnet för att öppna profilpanelen. Den är organiserad i hopfällbara sektioner:
Inställningar
Ändra UI-tema, textstorlek, färgschema, gränssnittsspråk och torrentrelaterade visningsinställningar. Ändringar sparas automatiskt.
Lösenord
Ange ditt nuvarande lösenord och det nya lösenordet två gånger. En verifieringskod skickas till din registrerade e-postadress och måste anges för att bekräfta ändringen. Om tvåfaktorsautentisering är aktiverat krävs din TOTP-kod också.
Tvåfaktorsautentisering (2FA)
Aktivera TOTP-baserad tvåfaktorsautentisering med valfri autentiseringsapp (t.ex. Google Authenticator, Aegis, Bitwarden). När du aktiverar 2FA:
- Skanna QR-koden (eller ange hemligheten manuellt) i din autentiseringsapp.
- Ange den 6-siffriga koden som visas i appen för att bekräfta inställningen.
- Spara de visade återställningskoderna — dessa är engångskoder för att återfå åtkomst om du förlorar din enhet.
För att inaktivera 2FA, ange din nuvarande TOTP-kod och bekräfta.
Aktiva sessioner
Visa alla nuvarande aktiva inloggningssessioner inklusive webbläsare, OS, IP-adress och tid för senaste aktivitet. Klicka på Återkalla på valfri session du inte känner igen. Du kan också återkalla alla sessioner på en gång för att logga ut från alla enheter.
API-nyckel
Generera en personlig API-nyckel som används för att programmatiskt ladda upp torrents via AniRena API. Klicka på Generera nyckel för att skapa en — den fullständiga nyckeln visas en gång direkt efter generering. Förvara den säkert; den visas inte i sin helhet igen. Använd Återkalla för att permanent ogiltigförklara nyckeln.
Radera konto
Begäran om kontoborttagning startar en 30-dagars avkylningstid. Ditt konto inaktiveras omedelbart och raderas permanent efter 30 dagar. Du kan avbryta raderingen när som helst inom det fönstret genom att logga in och klicka på Avbryt radering.
7. AniRena API
AniRena tillhandahåller ett JSON API som låter dig programmatiskt ladda upp torrents med en personlig API-nyckel. API:et tillämpar samma regler som webbgränssnittet: kontroller för blockeringar, hastighetsgränser och webbplatslägesbegränsningar gäller alla. Varje API-uppladdning registreras i granskningsloggen.
Autentisering
API:et använder ett autentiseringsflöde i två steg. Byt först din permanenta API-nyckel mot en kortlivad bearer-token, och skicka sedan den token i Authorization-headern för varje API-förfrågan.
Din API-nyckel finns under Ditt konto > API-nyckel. Håll den hemlig — vem som helst med nyckeln kan skaffa bearer-tokens och ladda upp i ditt namn. Om den komprometteras, återkalla den omedelbart och generera en ny.
Steg 1 — Skaffa en bearer-token
/api/v1/auth/tokenSkicka en POST-begäran till token-endpointen med din API-nyckel i Authorization-headern. Ingen begärandekropp krävs.
Authorization: ApiKey <your-api-key>
Token-svar
{
"token": "<bearer-token>",
"token_type": "Bearer",
"expires_in": 3600
}Tokenens livslängd
Bearer-tokens förblir giltiga i upp till 3600 sekunder från det att de utfärdades och kan återanvändas för varje anrop tills de upphör att gälla. När en token upphör att gälla, skapa en ny via POST /api/v1/auth/token. Varje svar returnerar fortfarande den aktuella token i X-New-Token-headern för bakåtkompatibilitet.
X-New-Token: <next-bearer-token>
Inloggning med en enda begäran (med 2FA)
/api/v1/auth/loginAutentisera med ditt användarnamn eller din e-post och ditt lösenord i en enda begäran och få ett bearer-token direkt. Om ditt konto har 2FA aktiverat, inkludera din aktuella autentiseringskod i totp_code (eller en återställningskod i recovery_code). Sätt eventuellt new_api_key till true för att även skapa en helt ny permanent API-nyckel i samma svar.
Förfrågningskropp
{
"login": "username or email",
"password": "your-password",
"totp_code": "123456", // krävs om 2FA är aktiverat (6 siffror)
"recovery_code": "", // alternativ till totp_code
"new_api_key": false // sätt till true för att även skapa en ny API-nyckel
}Token-svar
{
"ok": true,
"token": "<bearer-token>",
"token_type": "Bearer",
"expires_in": 3600,
"api_key": "<new-api-key>" // finns endast när new_api_key var true
}Bearer-token fungerar precis som ett från /api/v1/auth/token. Fältet api_key returneras endast när new_api_key är true — spara det omedelbart eftersom det bara visas en gång och ersätter eventuell tidigare nyckel.
Exempel — logga in och (valfritt) hämta en ny API-nyckel
# pip install requests import requests BASE_URL = "https://www.anirena.com" # One request: authenticate (with 2FA if enabled) and get a bearer token. # Set new_api_key=True to also receive a brand-new permanent API key. resp = requests.post( f"{BASE_URL}/api/v1/auth/login", json={ "login": "your-username", # username or email "password": "your-password", "totp_code": "123456", # omit if 2FA is not enabled "new_api_key": True, # optional }, ) resp.raise_for_status() data = resp.json() token = data["token"] # use as: Authorization: Bearer <token> if "api_key" in data: print("New API key — store it now:", data["api_key"])
// Built-in fetch — requires Node.js 18+ const BASE_URL = "https://www.anirena.com"; // One request: authenticate (with 2FA if enabled) and get a bearer token. // Set new_api_key:true to also receive a brand-new permanent API key. const resp = await fetch(`${BASE_URL}/api/v1/auth/login`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ login: "your-username", // username or email password: "your-password", totp_code: "123456", // omit if 2FA is not enabled new_api_key: true, // optional }), }); const data = await resp.json(); const token = data.token; // use as: Authorization: Bearer <token> if (data.api_key) console.log("New API key — store it now:", data.api_key);
// Requires: curl extension (enabled by default in PHP 8+) <?php define("BASE_URL", "https://www.anirena.com"); // One request: authenticate (with 2FA if enabled) and get a bearer token. // Set new_api_key => true to also receive a brand-new permanent API key. $ch = curl_init(BASE_URL . "/api/v1/auth/login"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode([ "login" => "your-username", // username or email "password" => "your-password", "totp_code" => "123456", // omit if 2FA is not enabled "new_api_key" => true, // optional ]), CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Content-Type: application/json"], ]); $data = json_decode(curl_exec($ch), true); curl_close($ch); $token = $data["token"]; // use as: Authorization: Bearer <token> if (isset($data["api_key"])) echo "New API key — store it now: " . $data["api_key"];
// Cargo.toml: // serde_json = "1" // reqwest = { version = "0.12", features = ["blocking", "json"] } const BASE_URL: &str = "https://www.anirena.com"; fn main() { let client = reqwest::blocking::Client::new(); // One request: authenticate (with 2FA if enabled) and get a bearer token. // Set new_api_key:true to also receive a brand-new permanent API key. let data: serde_json::Value = client .post(format!("{BASE_URL}/api/v1/auth/login")) .json(&serde_json::json!({ "login": "your-username", // username or email "password": "your-password", "totp_code": "123456", // omit if 2FA is not enabled "new_api_key": true, // optional })) .send().unwrap() .json().unwrap(); let token = data["token"].as_str().unwrap(); // Authorization: Bearer <token> if let Some(key) = data["api_key"].as_str() { println!("New API key — store it now: {key}"); } }
Steg 2 — Ladda upp en torrent
/api/v1/torrentsSkicka en enkel JSON POST-begäran med bearer-token i Authorization-headern.
Förfrågningskropp
| Fält | Typ | Krävs | Beskrivning |
|---|---|---|---|
torrent | string | Ja | Base64-kodat innehåll i .torrent-filen. |
category | string | Ja | Kategori-slug: anime, manga, audio, literature, live, pictures, software, hentai, other. |
name | string | Nej | Åsidosätt torrentens visningsnamn. |
sub_category | string | Nej | Underkategori-slug (t.ex. raw, sub-audio). Måste tillhöra den valda kategorin. |
languages | string[] | Nej | Array av BCP 47-språkkoder (t.ex. en, ja). |
group_id | string | Nej | UUID för en grupp du är medlem i för att associera med den här utgåvan. |
description | string | Nej | Markdown-formaterad utgåvabeskrivning (max 65535 tecken). |
comment | string | Nej | Åsidosätt det inbäddade torrentkommentarfältet. |
is_private | boolean | Nej | Ange true för att aktivera privatflaggan i torrenten. |
comments_enabled | boolean | Nej | Tillåt kommentarer på denna torrent. Standard är true (aktiverat). |
anime_id | string | Nej | UUID för ett anime-inlägg att länka till denna torrent. Hämta UUID via GET /api/v1/anime/search. Returnerar 400 om UUID inte matchar något känt inlägg. |
announce | string | Nej | Åsidosätt eller lägg till den primära announce URL. |
trackers | string | Nej | Nyradsseparerad lista med ytterligare tracker-URL:er. En tom rad mellan URL:er skapar en ny trackernivå. |
test | boolean | Nej | Ange true för en testkörning: begäran valideras fullt ut men torrenten sparas inte. Använd detta för att verifiera att din nyttolast är korrekt innan en verklig inlämning. |
Testkörning framgångssvar — 200 OK
{
"ok": true,
"test": true,
"name": "My Torrent Title",
"info_hash_v1": "aabbccddeeff...",
"info_hash_v2": null
}Tillgängliga språkkoder
abaaafaksqamarar-001anhyasavaeayazbmbaeubebnbhbibsbrbgmyyuecachcenyzhzh-HKzh-Hanszh-SGzh-TWcucvkwcocrhrcsdadvnlnl-BEdzenen-USeoeteefofjfilfifrfr-CAffgllgkadede-ATelgnguhthahehzhihohuisioigidiaieiuikgaitjajvklknkrkskkkmkirwrnkvkgkokjkukylolalvlilnltlulbmkmgmsmlmtgvmimrmhmnnanvngnendsenonbnnocorojomospipsfaplptpt-BRpaqurormrusmsgsascgdsrsr-Latnsniisdsiskslsonrsteses-419es-MXsuswsssvtltytgtatttethbotitotstntrtktwukuruguzvevivowacyfywoxhyiyozazuExempelförfrågan
# pip install requests import base64, pathlib, requests API_KEY = "YOUR_API_KEY" BASE_URL = "https://www.anirena.com" # Step 1: exchange API key for a short-lived bearer token auth = requests.post( f"{BASE_URL}/api/v1/auth/token", headers={"Authorization": f"ApiKey {API_KEY}"}, ) auth.raise_for_status() token = auth.json()["token"] # Step 2: upload — plain JSON with the bearer token torrent_b64 = base64.b64encode(pathlib.Path("file.torrent").read_bytes()).decode() resp = requests.post( f"{BASE_URL}/api/v1/torrents", json={ "torrent": torrent_b64, "category": "anime", "sub_category": "raw", "languages": ["ja"], "description": "# My Release\n\nRelease notes here.", "is_private": False, }, headers={"Authorization": f"Bearer {token}"}, ) resp.raise_for_status() data = resp.json() token = resp.headers.get("X-New-Token", token) # save for next request print(data["id"], data["name"]) # torrent UUID and title
// Built-in modules only — requires Node.js 18+ (for global fetch) const fs = require("fs"); const API_KEY = "YOUR_API_KEY"; const BASE_URL = "https://www.anirena.com"; // Step 1: exchange API key for a short-lived bearer token let authResp = await fetch(`${BASE_URL}/api/v1/auth/token`, { method: "POST", headers: { Authorization: `ApiKey ${API_KEY}` }, }); let { token } = await authResp.json(); // Step 2: upload — plain JSON with the bearer token const torrentB64 = fs.readFileSync("file.torrent").toString("base64"); const resp = await fetch(`${BASE_URL}/api/v1/torrents`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` }, body: JSON.stringify({ torrent: torrentB64, category: "anime", sub_category: "raw", languages: ["ja"], description: "# My Release\n\nRelease notes here.", is_private: false, }), }); const data = await resp.json(); token = resp.headers.get("x-new-token") ?? token; // save for next request console.log(data.id, data.name); // torrent UUID and title
// Requires: curl extension (enabled by default in PHP 8+) <?php define("API_KEY", "YOUR_API_KEY"); define("BASE_URL", "https://www.anirena.com"); // Step 1: exchange API key for a short-lived bearer token $ch = curl_init(BASE_URL . "/api/v1/auth/token"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: ApiKey " . API_KEY], ]); $token = json_decode(curl_exec($ch), true)["token"]; curl_close($ch); // Step 2: upload — plain JSON with the bearer token $torrentB64 = base64_encode(file_get_contents("file.torrent")); $respHeaders = []; $ch = curl_init(BASE_URL . "/api/v1/torrents"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode([ "torrent" => $torrentB64, "category" => "anime", "sub_category" => "raw", "languages" => ["ja"], "description" => "# My Release\n\nRelease notes here.", "is_private" => false, ]), CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADERFUNCTION => function($ch, $h) use (&$respHeaders) { $respHeaders[] = $h; return strlen($h); }, CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "Authorization: Bearer " . $token, ], ]); $data = json_decode(curl_exec($ch), true); curl_close($ch); foreach ($respHeaders as $h) { // save new token for next request if (stripos($h, "X-New-Token:") === 0) $token = trim(substr($h, strlen("X-New-Token:"))); } echo $data["id"] . " " . $data["name"]; // torrent UUID and title
// Cargo.toml: // base64 = "0.22" // serde_json = "1" // reqwest = { version = "0.12", features = ["blocking", "json"] } use base64::{engine::general_purpose::STANDARD as B64, Engine}; const API_KEY: &str = "YOUR_API_KEY"; const BASE_URL: &str = "https://www.anirena.com"; fn main() { let client = reqwest::blocking::Client::new(); // Step 1: exchange API key for a short-lived bearer token let auth: serde_json::Value = client .post(format!("{BASE_URL}/api/v1/auth/token")) .header("Authorization", format!("ApiKey {API_KEY}")) .send().unwrap().json().unwrap(); let mut token = auth["token"].as_str().unwrap().to_string(); // Step 2: upload — plain JSON with the bearer token let torrent_b64 = B64.encode(std::fs::read("file.torrent").unwrap()); let resp = client .post(format!("{BASE_URL}/api/v1/torrents")) .header("Authorization", format!("Bearer {token}")) .json(&serde_json::json!({ "torrent": torrent_b64, "category": "anime", "sub_category": "raw", "languages": ["ja"], "description": "# My Release\n\nRelease notes here.", "is_private": false })) .send().unwrap(); if let Some(t) = resp.headers().get("x-new-token") { token = t.to_str().unwrap().to_string(); // save for next request } let data: serde_json::Value = resp.json().unwrap(); println!("{} {}", data["id"], data["name"]); // torrent UUID and title }
Framgångsrikt svar — 200 OK
{
"ok": true,
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "My Torrent Title",
"info_hash_v1": "aabbccddeeff...",
"info_hash_v2": null
}Felsvar
| HTTP-status | Betydelse |
|---|---|
400 | Ogiltig förfrågningskropp eller saknat obligatoriskt fält. |
401 | Saknad, utgången eller redan roterad bearer-token. Autentisera om via POST /api/v1/auth/token. |
403 | Konto avstängt, inaktiverat eller IP blockerad. |
409 | Duplikattorrent — torrent med samma info-hash finns redan. |
422 | Torrent-filen kunde inte tolkas eller misslyckades med validering (förbjudet mönster, ogiltig struktur). |
429 | Hastighetsgräns överskriden. Försök igen när fönstret återställts. |
503 | Webbplatsen är i underhålls- eller skrivskyddat läge. |
Hastighetsbegränsning
API-uppladdningar är föremål för en konfigurerbar hastighetsgräns separat från webbgränssnittet. Gränsen och fönstret ställs in av webbplatsadministratören. När hastighetsgränsen överskrids returnerar API:et 429 Too Many Requests. Gränsen är per API-nyckel.
Generera torrent-filer med torrent-builder
torrent-builder är ett CLI-verktyg med öppen källkod byggt ovanpå libtorrent-rasterbar som låter dig skapa BitTorrent v1, v2 och hybrid .torrent-filer från kommandoraden. Det passar perfekt ihop med AniRena upload API — generera filen lokalt och POST den sedan direkt till trackern. cantalupo555/torrent-builder.
Bygg från källkod
Kräver CMake >= 3.28.3 och libtorrent-rasterbar >= 2.0.11. Klona repositoriet och bygg med CMake:
# Install system dependencies sudo apt-get install build-essential cmake libtorrent-rasterbar-dev # Clone & build git clone https://github.com/cantalupo555/torrent-builder.git cd torrent-builder mkdir build && cd build cmake .. && cmake --build .
# Install dependencies via Homebrew brew install cmake libtorrent-rasterbar # Clone & build git clone https://github.com/cantalupo555/torrent-builder.git cd torrent-builder mkdir build && cd build cmake .. && cmake --build .
Viktiga flaggor
| Fält | Beskrivning |
|---|---|
--path | Sökväg till filen eller katalogen som ska paketeras (obligatorisk). |
--output | Namn på utdata-.torrent-filen (obligatorisk). |
--version | BitTorrent-format — 1 = v1, 2 = v2, 3 = hybrid (standard: 3). |
--tracker | Lägg till en tracker-announce-URL. Upprepa flaggan för att lägga till flera trackers. |
--comment | Bädda in en metadatakommentarssträng i torrenten. |
--private | Sätt privatflaggan för att begränsa distributionen till enbart de listade trackerna. |
--piece-size | Delstorlek i KB (16-32768). Lämna oinställd för automatiskt val. |
-i | Starta stegvis interaktivt konfigurationsläge. |
Komplett arbetsflöde: bygg -> ladda upp
Exemplen nedan bygger en hybrid-torrent med torrent-builder, autentiserar sedan med AniRena API och laddar upp resultatet i ett enda skript.
# pip install requests import base64, subprocess, requests API_KEY = "YOUR_API_KEY" BASE_URL = "https://www.anirena.com" # Step 1: build the torrent with torrent-builder # --version 1=v1 2=v2 3=hybrid (default) subprocess.run([ "./torrent-builder/build/torrent_builder", "--path", "/data/my_release", "--output", "my_release.torrent", "--version", "3", # hybrid "--tracker", "udp://open.tracker.gg:6969/announce", "--comment", "My Release", "--creator", "--creation-date", ], check=True) # Step 2: authenticate token = requests.post( f"{BASE_URL}/api/v1/auth/token", headers={"Authorization": f"ApiKey {API_KEY}"}, ).json()["token"] # Step 3: upload torrent_b64 = base64.b64encode(open("my_release.torrent", "rb").read()).decode() resp = requests.post( f"{BASE_URL}/api/v1/torrents", json={ "torrent": torrent_b64, "category": "anime", "sub_category": "raw", "languages": ["ja"], "comments_enabled": True, }, headers={"Authorization": f"Bearer {token}"}, ) resp.raise_for_status() data = resp.json() print(data["id"], data["name"])
// Built-in modules — Node.js 18+ const fs = require("fs"); const { execFileSync } = require("child_process"); const API_KEY = "YOUR_API_KEY"; const BASE_URL = "https://www.anirena.com"; // Step 1: build the torrent (--version 1=v1, 2=v2, 3=hybrid) execFileSync("./torrent-builder/build/torrent_builder", [ "--path", "/data/my_release", "--output", "my_release.torrent", "--version", "3", "--tracker", "udp://open.tracker.gg:6969/announce", "--comment", "My Release", "--creator", "--creation-date", ]); // Step 2: authenticate let { token } = await (await fetch(`${BASE_URL}/api/v1/auth/token`, { method: "POST", headers: { Authorization: `ApiKey ${API_KEY}` }, })).json(); // Step 3: upload const torrentB64 = fs.readFileSync("my_release.torrent").toString("base64"); const resp = await fetch(`${BASE_URL}/api/v1/torrents`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` }, body: JSON.stringify({ torrent: torrentB64, category: "anime", sub_category: "raw", languages: ["ja"], comments_enabled: true, }), }); const data = await resp.json(); console.log(data.id, data.name);
// PHP 8+ with curl and proc_open <?php define("API_KEY", "YOUR_API_KEY"); define("BASE_URL", "https://www.anirena.com"); // Step 1: build the torrent (version: 1=v1, 2=v2, 3=hybrid) exec(implode(" ", array_map("escapeshellarg", [ "./torrent-builder/build/torrent_builder", "--path", "/data/my_release", "--output", "my_release.torrent", "--version", "3", "--tracker", "udp://open.tracker.gg:6969/announce", "--comment", "My Release", "--creator", "--creation-date", ]))); // Step 2: authenticate $ch = curl_init(BASE_URL . "/api/v1/auth/token"); curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: ApiKey " . API_KEY]]); $token = json_decode(curl_exec($ch), true)["token"]; curl_close($ch); // Step 3: upload $torrentB64 = base64_encode(file_get_contents("my_release.torrent")); $respHeaders = []; $ch = curl_init(BASE_URL . "/api/v1/torrents"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode([ "torrent" => $torrentB64, "category" => "anime", "sub_category" => "raw", "languages" => ["ja"], "comments_enabled" => true, ]), CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADERFUNCTION => function($ch, $h) use (&$respHeaders) { $respHeaders[] = $h; return strlen($h); }, CURLOPT_HTTPHEADER => ["Content-Type: application/json", "Authorization: Bearer " . $token], ]); $data = json_decode(curl_exec($ch), true); curl_close($ch); echo $data["id"] . " " . $data["name"];
// Cargo.toml: // base64 = "0.22" // serde_json = "1" // reqwest = { version = "0.12", features = ["blocking", "json"] } use base64::{engine::general_purpose::STANDARD as B64, Engine}; use std::process::Command; const API_KEY: &str = "YOUR_API_KEY"; const BASE_URL: &str = "https://www.anirena.com"; fn main() { // Step 1: build the torrent (--version 1=v1, 2=v2, 3=hybrid) Command::new("./torrent-builder/build/torrent_builder") .args([ "--path", "/data/my_release", "--output", "my_release.torrent", "--version", "3", "--tracker", "udp://open.tracker.gg:6969/announce", "--comment", "My Release", "--creator", "--creation-date", ]) .status().expect("torrent_builder failed"); let client = reqwest::blocking::Client::new(); // Step 2: authenticate let auth: serde_json::Value = client .post(format!("{BASE_URL}/api/v1/auth/token")) .header("Authorization", format!("ApiKey {API_KEY}")) .send().unwrap().json().unwrap(); let token = auth["token"].as_str().unwrap().to_string(); // Step 3: upload let torrent_b64 = B64.encode(std::fs::read("my_release.torrent").unwrap()); let resp: serde_json::Value = client .post(format!("{BASE_URL}/api/v1/torrents")) .header("Authorization", format!("Bearer {token}")) .json(&serde_json::json!({ "torrent": torrent_b64, "category": "anime", "sub_category": "raw", "languages": ["ja"], "comments_enabled": true, })) .send().unwrap().json().unwrap(); println!("{} {}", resp["id"], resp["name"]); }
Söka i torrent-metadata
/api/v1/torrents/searchSkicka en enkel JSON POST-begäran för att hämta torrentlistningar med samma sök- och filtreringsalternativ som finns på webbplatsen. .torrent-filen returneras inte — använd den normala nedladdningsvägen för det.
# pip install requests (token already obtained — see upload example) resp = requests.post( f"{BASE_URL}/api/v1/torrents/search", json={"q": "Sword Art Online", "category": "anime", "per_page": 25}, headers={"Authorization": f"Bearer {token}"}, ) resp.raise_for_status() data = resp.json() token = resp.headers.get("X-New-Token", token) # save for next request for t in data["torrents"]: print(t["title"], "-", t["magnet"])
// token already obtained — see upload example const resp = await fetch(`${BASE_URL}/api/v1/torrents/search`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` }, body: JSON.stringify({ q: "Sword Art Online", category: "anime", per_page: 25 }), }); const data = await resp.json(); token = resp.headers.get("x-new-token") ?? token; // save for next request data.torrents.forEach(t => console.log(t.title, "-", t.magnet));
// token already obtained — see upload example $respHeaders = []; $ch = curl_init(BASE_URL . "/api/v1/torrents/search"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode([ "q" => "Sword Art Online", "category" => "anime", "per_page" => 25 ]), CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADERFUNCTION => function($ch, $h) use (&$respHeaders) { $respHeaders[] = $h; return strlen($h); }, CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "Authorization: Bearer " . $token, ], ]); $data = json_decode(curl_exec($ch), true); curl_close($ch); foreach ($respHeaders as $h) { // save new token for next request if (stripos($h, "X-New-Token:") === 0) $token = trim(substr($h, strlen("X-New-Token:"))); } foreach ($data["torrents"] as $t) { echo $t["title"] . " - " . $t["magnet"] . "\n"; }
// client and token already obtained — see upload example let resp = client .post(format!("{BASE_URL}/api/v1/torrents/search")) .header("Authorization", format!("Bearer {token}")) .json(&serde_json::json!({"q": "Sword Art Online", "category": "anime", "per_page": 25})) .send().unwrap(); if let Some(t) = resp.headers().get("x-new-token") { token = t.to_str().unwrap().to_string(); // save for next request } let data: serde_json::Value = resp.json().unwrap(); for t in data["torrents"].as_array().unwrap() { println!("{} - {}", t["title"], t["magnet"]); }
Sökparametrar
| Fält | Typ | Krävs | Beskrivning |
|---|---|---|---|
q | string | Nej | Fritextsökning. Stöder group:slug, group:"Name", user:name prefix. |
category | string | Nej | Kategori-slug (t.ex. "anime"). |
sub_category | string | Nej | Underkategori-slug (t.ex. "raw"). |
languages | string[] | Nej | Array av BCP 47-språkkoder (t.ex. en, ja). |
sort | string | Nej | Sorteringsfält: date (standard), size, seeders, leechers, completed, title. |
order | string | Nej | Sorteringsriktning: desc (standard) eller asc. |
page | integer | Nej | Sidnummer, börjar vid 1 (standard 1). |
per_page | integer | Nej | Resultat per sida, 1–250 (standard 50). |
hide_adult | boolean | Nej | Uteslut torrents i vuxenkategorin. Standard true för vanliga användare. |
show_dead | boolean | Nej | När false (standard) exkluderas torrents äldre än dead-torrent-anståndsperioden utan aktiva seedare. Sätt till true för att inkludera dem. |
Svar
{
"total": 1234,
"page": 1,
"per_page": 50,
"total_pages": 25,
"from": 1,
"to": 50,
"torrents": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "My Release Title",
"info_hash_v1": "aabbccddeeff...",
"info_hash_v2": null,
"size_fmt": "1.4 GB",
"completed": 42,
"seeders": 10,
"leechers": 3,
"languages": ["ja", "en"],
"comment_count": 7,
"created_at": "2024-01-15 12:34",
"cat_slug": "anime",
"sub_slug": "raw",
"group_name": null,
"uploader": "username",
"magnet": "magnet:?xt=urn:btih:..."
}
]
}comment_count — Antal icke-raderade kommentarer på denna torrent.
Sökhastighetsbegränsning
Sökförfrågningar är föremål för en separat konfigurerbar hastighetsgräns (standard 60 förfrågningar per 60 sekunder per API-nyckel). Att överskrida gränsen returnerar 429 Too Many Requests. Personalkonton är undantagna.
Hämta torrentdetaljer
/api/v1/torrent/{id}Hämtar fullständig metadata för en enskild torrent — inklusive fält som sök-endpointen utelämnar, såsom Markdown-beskrivningen, den inbäddade .torrent-kommentaren, fillistan med storlek per fil och hela tracker-tier-layouten. När de är tillgängliga läses livesiffror för seeders och leechers från trackern.
Svar
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "My Release Title",
"info_hash_v1": "aabbccddeeff...",
"info_hash_v2": null,
"size_fmt": "1.4 GB",
"completed": 42,
"seeders": 10,
"leechers": 3,
"ext_seeders": 128,
"ext_leechers": 14,
"created_at": "2024-01-15 12:34",
"torrent_created": "2024-01-15 12:30",
"created_by_client": "mktorrent 1.1",
"cat_name": "Anime",
"cat_slug": "anime",
"sub_name": "Raw",
"sub_slug": "raw",
"group_name": null,
"group_slug": null,
"uploader": "username",
"uploader_id": "...",
"description": "# My Release\n\nRelease notes here.",
"comment": "",
"is_private": false,
"magnet": "magnet:?xt=urn:btih:...",
"languages": [
{ "code": "ja", "name": "Japanese", "country_code": "jp" }
],
"tracker_tiers": [
{ "tier": 0, "urls": ["udp://tracker.example.org:6969/announce"] }
],
"files": [
{ "path": "My Release/episode-01.mkv", "size": 1503238553 }
],
"comments_enabled": true,
"comments_locked": false,
"comment_count": 7
}seeders, leechers — Livesiffror från den interna trackern; båda rapporterar 0 när tracker-lagret saknar post för denna info hash eller är onåbart.
ext_seeders, ext_leechers — Högsta antal seeders och leechers som rapporterats av en enskild extern tracker scrapad för denna torrent. Trackers som följer samma svärm överlappar, så max används istället för summan; båda rapporterar 0 när ingen tracker har scrape-data för denna info hash.
Felsvar
| HTTP-status | Betydelse |
|---|---|
400 | Torrent-id:t måste vara antingen ett UUID på 36 tecken med bindestreck eller en 32 tecken lång ren hex-sträng. |
401 | Saknad, utgången eller redan roterad bearer-token. Autentisera om via POST /api/v1/auth/token. |
404 | Torrent hittades inte. |
429 | Hastighetsgräns överskriden. Försök igen när fönstret återställts. |
503 | Webbplatsen är i underhålls- eller skrivskyddat läge. |
Hämta torrent-kommentarer
/api/v1/torrents/{id}/commentsHämta sidnumrerade kommentarer för en torrent. Antalet kommentarer per sida styrs av COMMENT_PER_PAGE-inställningen i serverns .env-fil (standard 20). Bara torrents med aktiverade kommentarer returnerar resultat — alla andra returnerar 403.
Frågeparametrar
| Fält | Typ | Krävs | Beskrivning |
|---|---|---|---|
page | integer | Nej | Sidnummer, börjar vid 1 (standard 1). |
# pip install requests (token already obtained — see upload example) TORRENT_ID = "550e8400-e29b-41d4-a716-446655440000" resp = requests.get( f"{BASE_URL}/api/v1/torrents/{TORRENT_ID}/comments", params={"page": 1}, headers={"Authorization": f"Bearer {token}"}, ) resp.raise_for_status() data = resp.json() token = resp.headers.get("X-New-Token", token) # save for next request for c in data["comments"]: print(c["username"], "-", c["body"])
// token already obtained — see upload example const TORRENT_ID = "550e8400-e29b-41d4-a716-446655440000"; const resp = await fetch(`${BASE_URL}/api/v1/torrents/${TORRENT_ID}/comments?page=1`, { headers: { Authorization: `Bearer ${token}` }, }); const data = await resp.json(); token = resp.headers.get("x-new-token") ?? token; // save for next request data.comments.forEach(c => console.log(c.username, "-", c.body));
// token already obtained — see upload example $torrentId = "550e8400-e29b-41d4-a716-446655440000"; $respHeaders = []; $ch = curl_init(BASE_URL . "/api/v1/torrents/{$torrentId}/comments?page=1"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADERFUNCTION => function($ch, $h) use (&$respHeaders) { $respHeaders[] = $h; return strlen($h); }, CURLOPT_HTTPHEADER => ["Authorization: Bearer " . $token], ]); $data = json_decode(curl_exec($ch), true); curl_close($ch); foreach ($respHeaders as $h) { // save new token for next request if (stripos($h, "X-New-Token:") === 0) $token = trim(substr($h, strlen("X-New-Token:"))); } foreach ($data["comments"] as $c) { echo $c["username"] . " - " . $c["body"] . "\n"; }
// client and token already obtained — see upload example let torrent_id = "550e8400-e29b-41d4-a716-446655440000"; let resp = client .get(format!("{BASE_URL}/api/v1/torrents/{torrent_id}/comments?page=1")) .header("Authorization", format!("Bearer {token}")) .send().unwrap(); if let Some(t) = resp.headers().get("x-new-token") { token = t.to_str().unwrap().to_string(); // save for next request } let data: serde_json::Value = resp.json().unwrap(); for c in data["comments"].as_array().unwrap() { println!("{} - {}", c["username"], c["body"]); }
Svar
{
"torrent_id": "550e8400-e29b-41d4-a716-446655440000",
"page": 1,
"per_page": 20,
"total": 45,
"total_pages": 3,
"comments": [
{
"id": "...",
"user_id": "...",
"username": "uploader",
"role": "user",
"author_banned": false,
"body": "Great release!",
"created_at": "2024-01-15 12:34:00",
"edited_at": null,
"edited_by_username": null,
"deleted_at": null
}
]
}Fältet body är en tom sträng när kommentarförfattaren är avstängd eller kommentaren har tagits bort. Flaggan author_banned anger vilket fall som gäller.
Felsvar
| HTTP-status | Betydelse |
|---|---|
401 | Saknad, utgången eller redan roterad bearer-token. Autentisera om via POST /api/v1/auth/token. |
403 | Kommentarer är inaktiverade för denna torrent. |
404 | Torrenten hittades inte. |
503 | Webbplatsen är i underhålls- eller skrivskyddat läge. |
Söker efter animeposter
/api/v1/anime/search?q=<query>Sök efter anime-inlägg via titel för att hämta deras UUID. UUID kan skickas som anime_id i uppladdningskroppen för att länka en torrent till ett anime-inlägg vid uppladdningstillfället, eller användas med PUT /api/torrents/{id}/anime efter uppladdning. Ingen autentisering krävs. Underkastat samma hastighetsgräns som torrent-sökning (standard 60 förfrågningar per 60 sekunder per IP).
# pip install requests (no authentication required)
resp = requests.get(
f"{BASE_URL}/api/v1/anime/search",
params={"q": "Sword Art Online", "page": 1, "per_page": 10},
)
resp.raise_for_status()
for item in resp.json()["results"]:
print(item["id"], "-", item["title"])// No authentication required
const resp = await fetch(
`${BASE_URL}/api/v1/anime/search?q=${encodeURIComponent("Sword Art Online")}&page=1&per_page=10`
);
const data = await resp.json();
data.results.forEach(item => console.log(item.id, "-", item.title));// No authentication required
$ch = curl_init(BASE_URL . "/api/v1/anime/search?" . http_build_query([
"q" => "Sword Art Online", "page" => 1, "per_page" => 10,
]));
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
foreach ($data["results"] as $item) {
echo $item["id"] . " - " . $item["title"] . "\n";
}// No authentication required
let data: serde_json::Value = reqwest::blocking::get(
format!("{BASE_URL}/api/v1/anime/search?q=Sword+Art+Online&page=1&per_page=10")
).unwrap().json().unwrap();
for item in data["results"].as_array().unwrap() {
println!("{} - {}", item["id"], item["title"]);
}Frågeparametrar
| Fält | Typ | Krävs | Beskrivning |
|---|---|---|---|
q | string | Ja | Titelsöksträng (obligatorisk). Matchas mot titel och synonymer. |
page | integer | Nej | Sidnummer, börjar vid 1 (standard 1). |
per_page | integer | Nej | Resultat per sida, 1–50 (standard 10). |
Svar
{
"total": 42,
"page": 1,
"per_page": 10,
"total_pages": 5,
"results": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"title": "Sword Art Online",
"anime_type": "TV",
"episodes": 25,
"status": "FINISHED",
"season": "FALL",
"season_year": 2012,
"picture": "https://cdn.myanimelist.net/images/anime/...",
"thumbnail": "https://cdn.myanimelist.net/images/anime/...",
"duration_secs": 1440
}
]
}Lista och hämta grupper
/api/v1/groupsReturnerar en paginerad lista med offentliga grupper (aktiverade och olåsta). Kräver Bearer-tokenautentisering.
/api/v1/groups/{id_or_slug}Returnerar en enskild offentlig grupp efter numeriskt ID eller slug. Returnerar 404 om gruppen är inaktiverad eller låst.
Frågeparametrar (endast lista)
| Fält | Typ | Krävs | Beskrivning |
|---|---|---|---|
q | string | Nej | Filtrera efter gruppnamn (valfritt, delmatchning). |
page | integer | Nej | Sidnummer (standard 1). |
per_page | integer | Nej | Resultat per sida, 1–100 (standard 20). |
sort | string | Nej | Sorteringskolumn: name | slug | members | torrents | created (standard name). |
order | string | Nej | Sorteringsriktning: asc eller desc (standard asc). |
Svar (lista)
{
"total": 12,
"page": 1,
"per_page": 20,
"total_pages": 1,
"groups": [
{
"id": 1,
"name": "SubsPlease",
"slug": "subsplease",
"subdomain_slug": "subsplease",
"description": "Weekly simulcast batches.",
"owner": "admin",
"member_count": 42,
"torrent_count": 1337,
"created_at": "2024-01-15 12:34"
}
]
}Svar (enskild)
{
"id": 1,
"name": "SubsPlease",
"slug": "subsplease",
"subdomain_slug": "subsplease",
"description": "Weekly simulcast batches.",
"owner": "admin",
"member_count": 42,
"torrent_count": 1337,
"created_at": "2024-01-15 12:34"
}Felsvar
| HTTP-status | Betydelse |
|---|---|
401 | Saknad, utgången eller redan roterad bearer-token. Autentisera om via POST /api/v1/auth/token. |
404 | Grupp hittades inte eller är inte offentligt tillgänglig. |
429 | Hastighetsgräns överskriden. Försök igen när fönstret återställts. |
503 | Webbplatsen är i underhålls- eller skrivskyddat läge. |
8. Donationer
Om du vill stödja AniRena och hjälpa till att täcka kostnaderna för att vara värd för våra servrar och tjänster, är du välkommen att skicka en donation till en av följande kryptovaluta-plånböcker:
bc1qy2h3ddq6ak5damvnf4r5vu3ydehhxrcq8gllwn0xCbaFe03832F95F86AF2536d52710e78C63b62Cd33ucetj2XDGHQg9PVRPMxerNi7c6kX7GJkjQNg9yjwGegLbpt61yX3RjGtB1Ef8vgVz6Hr6baQsTjVkVarje donation, stor eller liten, är mycket uppskattad och går direkt till att hålla AniRena igång. Tack för ditt stöd!
9. Programvara
AniRena Player är en kostnadsfri skrivbordsapp som låter dig strömma video direkt från torrents som indexeras på den här webbplatsen — utan att behöva vänta på att hela nedladdningen ska bli klar. Klistra bara in en magnetlänk eller öppna en .torrent-fil, så börjar uppspelningen så snart tillräckligt med data finns tillgängligt.
Båda versionerna är helt fristående — alla beroenden är paketerade inuti den körbara filen. Ingen installerare, ingen körningsmiljö att konfigurera — ladda bara ner och kör.
Installationsprogram (.exe). Uppdaterar sig själv i appen.
Diskavbild (.dmg) för Apple Silicon-Mac (M1 och nyare). Uppdaterar sig själv i appen.
Diskavbild (.dmg) för Intel-Mac. Uppdaterar sig själv i appen.
Bärbar enkelfil, ingen installation behövs. Det enda Linux-formatet med uppdatering i appen.
Installation: sudo apt install ./<file>.deb — uppdateras via apt eller en ny nedladdning, inte i appen.
Installation: sudo dnf install ./<file>.rpm — uppdateras via dnf eller en ny nedladdning, inte i appen.
Sideload på 64-bitars ARM Android-enheter (de flesta moderna telefoner / surfplattor). Uppdateras genom att ladda ner en ny APK.
Äldre versioner
Sidladda på 32-bitars ARM Android-enheter (äldre telefoner / surfplattor). Uppdateras genom att ladda ner en ny APK.