REST API · v1

AniPub API
Documentation

Access a growing anime database including metadata, streaming links, MAL integration, and character data — all through a clean, fast REST API.

10k+ Anime Listed
5 Endpoints
Free No Auth Required
Base URL https://www.anipub.xyz
Introduction

The AniPub API provides programmatic access to anime metadata, streaming sources, character information, and MyAnimeList-integrated data. All endpoints are publicly accessible over HTTPS — no API key or authentication needed.

All responses are in JSON format. The API uses standard HTTP status codes. CORS is enabled for browser-based requests.
When an ImagePath or Cover field does not start with https://, prepend https://anipub.xyz/ to construct the full URL.
Authentication

No authentication is required. All endpoints are open and do not require API keys, OAuth tokens, or any headers beyond standard HTTP.

Simply make requests to any endpoint. Rate limiting may apply for excessive usage.
Error Codes
StatusMeaningDescription
200OKRequest succeeded
400Bad RequestMissing or invalid parameters
404Not FoundAnime with given ID not found
500Server ErrorInternal server issue
GET /api/info/:id Get Anime Info

Returns metadata for a specific anime by its integer ID. IDs start from 1 and go up to the total count returned by /api/getAll.

ParameterTypeRequiredDescription
id integer Required Anime ID — must be ≥ 1
Node.js
Python
PHP
cURL
Go
Ruby
javascript
const fetch = require('node-fetch'); // or use built-in fetch (Node 18+)

async function getAnimeInfo(id) {
  const response = await fetch(`https://www.anipub.xyz/api/info/${id}`);

  if (!response.ok) {
    throw new Error(`HTTP error: ${response.status}`);
  }

  const data = await response.json();

  // Resolve relative image paths
  const resolveImg = path =>
    path.startsWith('https://') ? path : `https://anipub.xyz/${path}`;

  data.ImagePath = resolveImg(data.ImagePath);
  data.Cover     = resolveImg(data.Cover);

  return data;
}

getAnimeInfo(1).then(console.log).catch(console.error);
python
import requests

def get_anime_info(anime_id: int) -> dict:
    url = f"https://www.anipub.xyz/api/info/{anime_id}"
    response = requests.get(url)
    response.raise_for_status()
    data = response.json()

    # Resolve relative image paths
    def resolve_img(path):
        return path if path.startswith("https://") else f"https://anipub.xyz/{path}"

    data["ImagePath"] = resolve_img(data["ImagePath"])
    data["Cover"]     = resolve_img(data["Cover"])
    return data

anime = get_anime_info(1)
print(anime["Name"], anime["MALScore"])
php
<?php

function getAnimeInfo($id) {
    $url = "https://www.anipub.xyz/api/info/" . intval($id);
    $ch  = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $body = curl_exec($ch);
    curl_close($ch);

    $data = json_decode($body, true);

    // Resolve relative image paths
    foreach (['ImagePath', 'Cover'] as $key) {
        if (!str_starts_with($data[$key], 'https://')) {
            $data[$key] = 'https://anipub.xyz/' . $data[$key];
        }
    }

    return $data;
}

$anime = getAnimeInfo(1);
echo $anime['Name'] . ' — Score: ' . $anime['MALScore'];
?>
bash
# Get anime info for ID 1
curl -X GET "https://www.anipub.xyz/api/info/1" \
  -H "Accept: application/json"

# Pretty print with jq
curl -s "https://www.anipub.xyz/api/info/1" | jq '.'

# Extract just name and score
curl -s "https://www.anipub.xyz/api/info/1" | \
  jq '{name: .Name, score: .MALScore, genres: .Genres}'
go
package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "strings"
)

type AnimeInfo struct {
    ID        int      `json:"_id"`
    Name      string   `json:"Name"`
    ImagePath string   `json:"ImagePath"`
    Cover     string   `json:"Cover"`
    MALScore  string   `json:"MALScore"`
    Genres    []string `json:"Genres"`
    Status    string   `json:"Status"`
}

func resolveImg(path string) string {
    if strings.HasPrefix(path, "https://") {
        return path
    }
    return "https://anipub.xyz/" + path
}

func getAnimeInfo(id int) (AnimeInfo, error) {
    url := fmt.Sprintf("https://www.anipub.xyz/api/info/%d", id)
    resp, err := http.Get(url)
    if err != nil { return AnimeInfo{}, err }
    defer resp.Body.Close()

    var anime AnimeInfo
    json.NewDecoder(resp.Body).Decode(&anime)
    anime.ImagePath = resolveImg(anime.ImagePath)
    anime.Cover     = resolveImg(anime.Cover)
    return anime, nil
}
ruby
require 'net/http'
require 'json'
require 'uri'

def get_anime_info(id)
  uri  = URI.parse("https://www.anipub.xyz/api/info/#{id}")
  resp = Net::HTTP.get_response(uri)
  data = JSON.parse(resp.body)

  # Resolve relative image paths
  ['ImagePath', 'Cover'].each do |key|
    data[key] = "https://anipub.xyz/#{data[key]}" unless data[key].start_with?('https://')
  end
  data
end

anime = get_anime_info(1)
puts "#{anime['Name']} — MAL Score: #{anime['MALScore']}"

▶ GET /api/info/:id

200 OK application/json
{
  "_id": 1,
  "Name": "Onmyou Kaiten Re:Birth",
  "ImagePath": "onmyou-kaiten-rebirth.webp",  // → prepend https://anipub.xyz/ if no https://
  "Cover": "onmyou-kaiten-rebirth1.webp",
  "Synonyms": "Onmyou Kaiten Re:verse",
  "Aired": "Jul 3, 2025 to ?",
  "Premiered": "Summer 2025",
  "RatingsNum": 35,
  "Genres": ["action", "fantasy"],
  "Studios": "Aniplex, Shueisha, ufotable, Aniplex of America",
  "Producers": "David Production",
  "DescripTion": "Onmyo Kaiten Re : Birth Verse anime...",
  "Duration": "23m",
  "MALScore": "6.8",
  "Status": "Ongoing",
  "epCount": 5
}
Sample Anime Card Built From Response
Poster
Onmyou Kaiten Re:Birth
AKA: Onmyou Kaiten Re:verse
action fantasy
Studio ufotable
Duration 23m
★ 6.8
● Ongoing
Premiered Summer 2025
Episodes 5
GET /api/getAll Get Total Count

Returns an integer representing the total number of anime entries currently in the database. Use this to know the valid ID range for other endpoints.

Node.js
Python
cURL
PHP
javascript
const res   = await fetch('https://www.anipub.xyz/api/getAll');
const total = await res.json();   // e.g. 1030

console.log(`Database has ${total} anime entries`);
console.log(`Valid IDs: 1 → ${total}`);
python
import requests

total = requests.get("https://www.anipub.xyz/api/getAll").json()
print(f"Total anime: {total} | Valid IDs: 1 to {total}")
bash
curl -s "https://www.anipub.xyz/api/getAll"
# Returns: 1030
php
$total = json_decode(file_get_contents('https://www.anipub.xyz/api/getAll'));
echo "Total: $total | Valid IDs: 1–$total";

▶ GET /api/getAll

200 OK Returns a plain integer
1030
GET /v1/api/details/:id Get Streaming Links

Returns iframe streaming links for a specific anime including per-episode links. The link field contains src=https://... suitable for iframe embeds. Note: the _id field may now be a MongoDB ObjectId string.

The _id field is deprecated as an integer. It may be a MongoDB ObjectId string like "68971dc4e9396134d130f8e8". Use the URL parameter :id as the authoritative identifier.
ParameterTypeRequiredDescription
idintegerRequiredAnime ID (1 to getAll value)
Node.js
Python
cURL
PHP
javascript
async function getStreamLinks(id) {
  const res  = await fetch(`https://www.anipub.xyz/v1/api/details/${id}`);
  const data = await res.json();
  const { local } = data;

  // Convert "src=URL" → iframe-ready string
  const toIframeSrc = link => link.replace('src=', '');

  const mainLink  = toIframeSrc(local.link);
  const epLinks   = local.ep.map((e, i) => ({
    episode: i + 1,
    src: toIframeSrc(e.link)
  }));

  return { mainLink, epLinks, name: local.name };
}

getStreamLinks(119).then(d => {
  console.log(`Anime: ${d.name}`);
  d.epLinks.forEach(e => console.log(`EP ${e.episode}: ${e.src}`));
});
python
import requests

data  = requests.get("https://www.anipub.xyz/v1/api/details/119").json()
local = data["local"]

print(f"Anime: {local['name']}")

for i, ep in enumerate(local["ep"], 1):
    src = ep["link"].replace("src=", "")
    print(f"Episode {i}: {src}")
bash
curl -s "https://www.anipub.xyz/v1/api/details/119" | jq '.local.ep[].link'
php
$data  = json_decode(file_get_contents('https://www.anipub.xyz/v1/api/details/119'), true);
$local = $data['local'];
foreach ($local['ep'] as $i => $ep) {
    $src = str_replace('src=', '', $ep['link']);
    echo "EP " . ($i+1) . ": $src\n";
}

▶ GET /v1/api/details/:id

Episode Links Rendered From Response
1
2
3
4
5
6
GET /anime/api/details/:id Full Anime Details + MAL + Characters

Returns the most comprehensive dataset: local anime info, full MyAnimeList data via Jikan API integration, and character list with voice actors. Best endpoint for rich anime pages.

Node.js
Python
cURL
PHP
Go
javascript
async function getFullDetails(id) {
  const res  = await fetch(`https://www.anipub.xyz/anime/api/details/${id}`);
  const { local, jikan, characters } = await res.json();

  const resolveImg = p =>
    p?.startsWith('https://') ? p : `https://anipub.xyz/${p}`;

  return {
    title:    local.Name,
    poster:   resolveImg(local.ImagePath),
    cover:    resolveImg(local.Cover),
    score:    local.MALScore,
    genres:   local.Genres,
    malData:  jikan,
    trailer:  jikan.trailer?.embed_url,
    cast:     characters.map(c => ({
      name:  c.character.name,
      role:  c.role,
      image: c.character.images.webp.image_url,
      vas:   c.voice_actors
    }))
  };
}

getFullDetails(119).then(d => {
  console.log(`${d.title}${d.cast.length} characters`);
});
python
import requests

data       = requests.get("https://www.anipub.xyz/anime/api/details/119").json()
local      = data["local"]
jikan      = data["jikan"]
characters = data["characters"]

print(f"Title: {local['Name']}")
print(f"MAL Score: {local['MALScore']}")
print(f"Synopsis: {jikan['synopsis'][:200]}...")
print("\nMain Cast:")
for char in characters:
    print(f"  {{char['character']['name']}} ({{char['role']}})")
bash
# Full details
curl -s "https://www.anipub.xyz/anime/api/details/119" | jq '.'

# Just characters
curl -s "https://www.anipub.xyz/anime/api/details/119" | \
  jq '.characters[] | {name: .character.name, role}'

# Local + MAL score comparison
curl -s "https://www.anipub.xyz/anime/api/details/119" | \
  jq '{local_score: .local.MALScore, mal_score: .jikan.score}'
php
$data       = json_decode(file_get_contents('https://www.anipub.xyz/anime/api/details/119'), true);
$local      = $data['local'];
$characters = $data['characters'];

foreach ($characters as $char) {
    echo $char['character']['name'] . ' — ' . $char['role'] . "\n";
}
go
resp, _ := http.Get("https://www.anipub.xyz/anime/api/details/119")
defer resp.Body.Close()

var result struct {
    Local      struct{ Name string `json:"Name"` }        `json:"local"`
    Characters []struct{
        Character struct{ Name string `json:"name"` } `json:"character"`
        Role      string                                `json:"role"`
    } `json:"characters"`
}

json.NewDecoder(resp.Body).Decode(&result)
fmt.Println(result.Local.Name)

▶ GET /anime/api/details/:id

Character & Voice Actor Grid
Shizuka
Masuda, Shizuka
Main Character
Japanese
Ryo
Mizuhara, Ryo
Main Character
Japanese
Yurika
Meno, Yurika
Supporting
Japanese
Akane
Mizuhara, Akane
Supporting
Japanese
Rich Anime Card
JJK Culling Game
Jujutsu Kaisen: The Culling Game Part 1
AKA: Jujutsu Kaisen 3rd Season
action drama school shounen supernatural
Studio MAPPA
Producer TOHO animation
★ 8.31
● Ongoing
Premiered Winter 2026
Episodes 6
POST /api/check Check Anime Match

Checks if a given anime name and genre combination exists in the database. Pass the anime name and one or more genres; the API returns match data.

Body FieldTypeRequiredDescription
Name string Required Name of the anime to search for
Genre string | array Required Genre string or array of genre strings. e.g. 'Action' or ['Action','Drama']
Node.js
Python
cURL
PHP
Axios
javascript (fetch)
const checkAnime = async (name, genre) => {
  const res = await fetch("https://anipub.xyz/api/check", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ Name: name, Genre: genre })
  });
  return res.json();
};

// Single genre
await checkAnime("Jujutsu Kaisen", "Action");

// Multiple genres
await checkAnime("Jujutsu Kaisen", ["Action", "Drama"]);
python
import requests

payload = {
    "Name":  "Jujutsu Kaisen",
    "Genre": ["Action", "Drama"]   # or "Action" as a string
}

res = requests.post(
    "https://anipub.xyz/api/check",
    json=payload
)

print(res.json())
bash
# Single genre
curl -X POST "https://anipub.xyz/api/check" \
  -H "Content-Type: application/json" \
  -d '{"Name":"Jujutsu Kaisen","Genre":"Action"}'

# Array of genres
curl -X POST "https://anipub.xyz/api/check" \
  -H "Content-Type: application/json" \
  -d '{"Name":"Jujutsu Kaisen","Genre":["Action","Drama"]}'
php
$payload = json_encode([
    'Name'  => 'Jujutsu Kaisen',
    'Genre' => ['Action', 'Drama']
]);

$ch = curl_init('https://anipub.xyz/api/check');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => $payload,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
]);
$result = json_decode(curl_exec($ch), true);
var_dump($result);
javascript (axios)
import axios from 'axios';

const { data } = await axios.post('https://anipub.xyz/api/check', {
  Name:  'Jujutsu Kaisen',
  Genre: ['Action', 'Drama']
});

console.log('Name match:',  data.nameMatch);
console.log('Genre match:', data.genreMatch);

▶ POST /api/check

Sample Check Result
Match Found
Name: Jujutsu Kaisen · Genre: Action · Both match the database
⚡ API Playground

Build and send any request to the AniPub API directly from here. Mix and match endpoints and IDs.