Sources and licensing
Where every fact in the dataset comes from, under what terms it was taken, and what that means for you if you use it. This page describes the project’s position; it is not legal advice.
The short version
The code and the data are licensed separately:
| Licence | File | |
|---|---|---|
Code — everything except data/ | MIT | LICENSE |
data/ as a database | ODbL v1.0 | LICENSE-DATA |
data/ individual records | DbCL v1.0 | same file |
Attribution for the upstream sources lives in
NOTICE.
The sources
| Source | Licence | What it contributes |
|---|---|---|
| anime-offline-database | ODbL + DbCL | titles, release year and season, episode counts, cross-provider ids |
| Anime-Lists | none stated | the AniDB→TVDB id mapping (tvdbId), movie-set grouping hints |
| Wikidata | CC0 | character and staff names — and nothing else; the cast structure around them is authored |
| This project | ODbL (as published here) | franchise and series grouping, ids, season and part numbers, absoluteNumber, watch orders |
The last row is the part with no upstream at all. Deciding that Fate/Zero and Fate/stay night are two series of one franchise, that Golden Kamuy’s five seasons carry a continuous episode numbering, or that Trigun Stargaze is season two of Stampede — none of that is in any source. It is the project’s editorial work, and it is why the dataset exists.
Where each field comes from
Provenance in this dataset is per field, not per file — every record in
data/ mixes all four rows above. This table is the authoritative mapping,
keyed by the field path as it appears in a data/series/*.yaml or
data/staff/*.yaml record.
Throughout, an authored value always wins: the builder only fills a field the override left empty, merging per field rather than per object. So any field below marked as upstream-filled may instead be the project’s own value where an override supplied one.
| Field | Filled from | Licence |
|---|---|---|
franchise.id, series.id, seasons[].id, movies[].id, specials[].id, *.characters[].id, staff[].id | this project — authored slugs | ODbL |
franchise.titles, series.titles | this project — a franchise or series grouping has no upstream entry, so its title must be authored | ODbL |
seasons[].titles, movies[].titles, specials[].titles | anime-offline-database — original and ja from the native-script title (or the first native-script synonym), en from the Latin main title | ODbL + DbCL |
seasons[].number, seasons[].part | this project — editorial | ODbL |
seasons[].releaseYear, seasons[].releaseSeason, movies[].releaseYear, specials[].releaseYear | anime-offline-database — its animeSeason block | ODbL + DbCL |
*.episodes[].airedNumber | anime-offline-database — the episode count, expanded to 1…n; the same on a season and on a special | ODbL + DbCL |
seasons[].episodes[].absoluteNumber, movies[].absoluteNumber | this project — assignAbsoluteNumbers interleaves season episodes and original movies by release order; an alternate cut takes no number of its own | ODbL |
*.externalIds.anilistId | this project — the authored join key on whichever node carries it, cross-checked against anime-offline-database’s sources array (see below) | ODbL |
seasons[].externalIds.anidbId, movies[].externalIds.anidbId, specials[].externalIds.anidbId | anime-offline-database — parsed from its sources array. Only these three node kinds are resolved against it | ODbL + DbCL |
seasons[].externalIds.tvdbId, movies[].externalIds.tvdbId, specials[].externalIds.tvdbId | Anime-Lists — the AniDB→TVDB map, keyed by the anidbId above | none stated |
*.externalIds.wikidataId | this project — the authored QID join key; in practice only cast nodes carry one | ODbL |
*.characters[].names, staff[].names | Wikidata — the ja label becomes original and ja, the en label becomes en | CC0 |
*.characters[].voiceActors[], *.characters[].appearances[] | this project — the cast structure is authored by hand in config/overrides/, with Wikidata used as a research aid rather than extracted from | ODbL |
movies[].alternateCutOf | this project — Anime-Lists movie sets only report a grouping hint during a build; nothing from them is written to data/ | ODbL |
franchise.watchOrders, numbered | this project — editorial | ODbL |
What the schema allows but the builder never fills
None of the following appears in the current data/. If one ever does, it was
authored, and the row above that names its source does not apply to it.
*.externalIds.tmdbId,*.releaseDateand*.episodes[].title— nothing in the build writes these anywhere.*.characters[].externalIds.anidbId,*.characters[].externalIds.tvdbId,staff[].externalIds.anidbId,staff[].externalIds.tvdbId— a cast node is resolved by QID against Wikidata, never against anime-offline-database or Anime-Lists, so the two rows above cover season, movie and special only.specials[].absoluteNumberandspecials[].episodes[].absoluteNumber— the numbering pass builds its run from seasons and movies, so nothing under a special is ever numbered.specials[].formatwould default from anime-offline-database’s media type, but the catalogue holds no specials, so it is unused too.
The schema is deliberately permissive here — one externalIds shape is shared
by every kind of node — so “the schema allows it” is not evidence that anything
fills it.
Why data/ is not split by source
A natural question is whether data/ should be organised as
data/anime-offline-database/, data/wikidata/ and so on, so that each
directory carries one licence. It should not, for two reasons.
The seam is between fields, not between files. As the table above shows, a
single data/series/*.yaml record interleaves all four provenances — titles
from anime-offline-database, one tvdbId from Anime-Lists, character names from
Wikidata, and the ids, numbering and grouping from this project. Splitting by
source would shatter every series across three or four files that consumers must
re-join, and would still be coarser than this table, which answers the
question at the level it is actually asked.
It would not change the licensing answer, and would misstate it. data/ as
a whole is a derivative database of an ODbL source (see below), so ODbL reaches
all of it. A directory named data/wikidata/ would read as “this part is CC0,
take it freely” — but the arrangement it carries, keyed to ids that exist only
because of the project’s editorial structure, is not. One honest licence over
the joined result is a stronger statement than four directory names.
The place where one directory per source is the right model is .sources/ —
the raw upstream snapshots pulled by builder init, one file per source,
untouched and unjoined. data/ is the joined output, and joining is the point
of it.
Why the data is under ODbL
data/ is built from anime-offline-database, so it is a derivative database
of an ODbL source, and ODbL’s share-alike term reaches derivative databases —
not just verbatim copies. The dataset is therefore offered on the same terms it
was received under. That is an obligation inherited from the source, not a
preference.
Two consequences worth being explicit about:
- Sharing a modified dataset publicly means sharing it under ODbL too. If
you extend, correct or re-derive
data/and make it publicly available, the result carries the same licence. - The terms travel with binaries.
dataset.goembedsdata/withgo:embed, so a compiledcmd/apibinary — or a deployment of it — contains the database. It is not only the YAML files that are covered.
A Produced Work built from the data — a chart, an article, an app screen — is treated differently by ODbL and needs attribution rather than share-alike. The dataset itself, and an API that returns it, are not Produced Works.
Anime-Lists has no stated licence
The project publishes no licence file. What the build takes from it is bare identifier pairs — numbers linking one public database to another — which this project treats as facts rather than protected expression, and which are widely vendored on that basis. That reasoning is stated plainly rather than hidden because it is the weakest link in the chain: if you are redistributing this dataset in a context where that matters, reach your own view.
Why AniList ids appear but AniList data does not
AniList’s Terms of Service prohibit using its API as a backup or data storage
service and prohibit mass collection, so the build never calls AniList and no
AniList content is stored or served. There is no AniList endpoint in
config.yaml.
The anilistId on every node is an identifier parsed out of the
cross-reference URLs that anime-offline-database publishes — the same array
that yields anidbId, myAnimeListId and kitsuId. It is a join key into the
ODbL source, not AniList data.
This is the point of the “facts, not expression” rule the dataset follows throughout: the dataset stores ids, names and structure, and leaves synopses, artwork, ratings and biographies to be fetched live at runtime from whichever service the consumer has a right to use. See Using the dataset.
If you redistribute this dataset
Keep NOTICE
intact, credit this project and the upstream sources, and offer any publicly
released derivative database under ODbL. If you only publish a Produced Work
built from the data, attribution is enough.