{"mock":"https://private-anon-668f1cb89c-grobber.apiary-mock.com/","production":"https://mas.dokkeral.com/","proxy":"https://private-anon-668f1cb89c-grobber.apiary-proxy.com/"}
FORMAT: 1A
HOST: https://mas.dokkeral.com
# Grobber
Grobber is a powerful API providing you with all the Anime and Manga
you could ever need.
**Grobber is not a meta data provider**. If that's what you're looking
for, refer to the [Kitsu API][kitsu-api]. It is an API designed to
provide an easy way to fetch Anime episodes.
[kitsu-api]: https://kitsu.docs.apiary.io
Due to the way it's designed Grobber is also rather slow as most
operations are only performed once requested.
# Introduction
## UID
UIDs are used to uniquely represent Grobber objects. They are an
essential part of interacting with the API.
Each UID composes all the necessary information to identify an entity.
The most variadic part of an UID is the medium id which is derived from
the title of the medium and sanitised using the following steps:
1. Convert the entire title to lowercase and remove all spaces
2. Find all non-alphanumeric characters (a-z and 0-9) and replace
them according to the following scheme:
1. Get the integer Unicode codepoint for this character
2. Wrap the hexadecimal representation of said integer with underscores
UIDs without a medium source refer to groups. Groups combine all mediums
with the same medium id.
### Format
EBNF:
```
medium type = "a" | "m" ;
escaped character = "_" , hexadecimal character , { hexadecimal character } , "_" ;
medium id character = lowercase letter | digit | escaped character ;
medium id = medium id character , { medium id character } ;
medium source = lowercase letter , { lowercase letter } ;
language = "en" | "de" ;
uid = medium type , "-" , medium id , [ "-" , medium source ] , "-" , language , [ "_dub" ] ;
```
or simplified:
`medium_type-medium_id(-source?)-language(_dub)?`
And here's a regular expression to parse an UID if you ever come across one.
RegExp:
```
^(a|m)-([a-z0-9_]*)(?:-([a-z]*))?-([a-z]+?)(_dub)?$
```
### Version 1 (Deprecated)
The previous version of the UID format had the following format:
```
medium id character = lowercase letter | digit | "_" ;
medium id = medium id character , { medium id character } ;
medium source = lowercase letter , { lowercase letter } ;
language = "en" | "de" ;
uid = medium source , "-" , medium id , "-" , language , [ "_dub" ] ;
```
Grobber still accepts it but you shouldn't use it as the format can't
encode all possible medium ids.
# Examples
## Dolos
If you're looking for a reference implementation look no further than Dolos,
a browser extension which uses Grobber to embed an episode player on popular
Anime database sites.
You can find the TypeScript code over at [Dolos' GitHub repository][dolos].
Most of the code regarding Grobber can be found in the [`grobber/client.ts` file][dolos-client-file].
[dolos]: https://github.com/MyAnimeStream/dolos
[dolos-client-file]: https://github.com/MyAnimeStream/dolos/blob/master/src/grobber/client.ts
# Group Anime
## Anime [/anime]
These are the endpoints you'll want to use to search for and enquire
more information about Anime.
### Search Anime [GET /anime/search/{?anime}{?language}{?dubbed}{?group}{?results}]
Based on a query (i.e. the name of an Anime) it returns matching results.
Use this endpoint to get an accurate match for a title, for actual
search requests you should use the indexsearch endpoint.
Depending on the amount of results (up to `20`) you request,
this operation can take a long time. **You should seldom request search results**
and if you do you should store the details of the result(s)!
The search results are already sorted in descending order by their `certainty` attribute.
+ Parameters
+ anime (string, required, `One Piece`) ... Title of the Anime
+ language (string, optional, `en`) ... Filter for language, defaults
to `en`
+ dubbed (boolean, optional, `false`) ... Filter translation type,
defaults to `false`
+ group (boolean, optional, `true`) ... Whether or not to group
results with the same medium id or not, defaults to `true`
+ results (number, optional, `3`) ... Amount of (SearchResult)s to
return, defaults to `1`
+ Response 200 (application/json)
+ Attributes
+ anime (array)
- (SearchResult)
### Search Anime in index [GET /anime/indexsearch/{?query}{?language}{?dubbed}{?group}{?page}{?results}]
Searching for multiple anime using the `search` endpoint is slow. If you
want to search for a lot of results or simply need speedy results you
can use this endpoint.
This endpoint also supports pagination using the page parameter. The
result items are (Medium) objects.
+ Parameters
+ query (string, required, `One Piece`) ... Query to search for
+ language (string, optional, `en`) ... Filter for language,
defaults to `en`
+ dubbed (boolean, optional, `false`) ... Filter translation type,
defaults to `false`
+ group (boolean, optional, `true`) ... Whether or not to group
results with the same medium id or not, defaults to `true`
+ page (number, optional, `0`) ... Page index to return, defaults to
0
+ results (number, optional, `20`) ... Amount of (SearchResult)s to
return for the page, defaults to 20
+ Response 200 (application/json)
+ Attributes
+ anime (array)
- (SearchResult)
### Get Anime using UID [GET /anime/{?uid}]
The best way to target an anime is by using its UID. A uid (unique identifier), as its name implies,
uniquely identifies an Anime, including the language and translation type.
+ Parameters
+ uid (string, required, `a-onepiece-masteranime-en`) ... UID to look for
+ Response 200 (application/json)
+ Attributes
+ anime (Anime)
### Get Anime using Title [GET /anime/{?anime}{?language}{?dubbed}{?group}]
**Status**: Deprecated, use UIDs.
You can also use the Anime's title to "identify" it.
> Beware that there might be multiple Anime with the same name!
> This method doesn't uniquely identify an Anime.
+ Parameters
+ anime (string, required, `One Piece`) ... Title of the Anime
+ language (string, optional, `en`) ... Filter for language, defaults to `en`
+ dubbed (boolean, optional, `false`) ... Filter translation type, defaults to `false`
+ group (boolean, optional, `true`) ... Group results with the same
medium id, defaults to `true`.
+ Response 200 (application/json)
+ Attributes
+ anime (Anime)
## Episode [/anime/episode]
Now let's look at the interesting stuff, episodes.
In order to get an episode you first need to know about the Anime though,
do read up on that if you haven't already.
### Get Episode [GET /anime/episode/{?uid}{?episode}]
> Instead of using the uid of an Anime you may also use the same parameters
> as seen in [**Get Anime using Title**](#reference/anime/anime/get-anime-using-title)
+ Parameters
+ uid (string, required, `a-onepiece-masteranime-en`) ... UID to look for
+ episode (number, required, `5`) ... Episode **index** to fetch. Keep in mind that this is the **index** (i.e. it starts from 0 and goes to \<amount of episodes\> - 1 inclusive!)
+ Response 200 (application/json)
+ Attributes
+ anime (Anime)
+ episode (Episode)
# Group Misc
## Grobber Info [/grobber-info]
Get some basic information about this Grobber server.
This endpoint used to be available under `/dolos-info` which is now
**deprecated**!
### Get Info [GET]
+ Response 200 (application/json)
+ Attributes
+ id: `grobber`
+ version: `3.0.26`
# Data Structures
## Medium (object)
+ Include Anime
+ aliases (array) - Array of aliases
+ episode_count: 868 (number, required) - Same as `episodes`
## Anime (object)
+ title: `One Piece` (string, required)
+ media_id: `onepiece` (string, required)
+ uid: `a-onepiece-masteranime-en` (string, required)
+ language: `en` (string, required)
+ dubbed: false (boolean, required)
+ thumbnail: `https://cdn.masterani.me/poster/646ILh0X4F.jpg` (string, optional)
+ episodes: 868 (number, required)
+ updated: `2018-12-30T15:41:23.168227` (string, optional) - ISO 8601 timestamp of last update
## Episode (object)
+ embeds (array[string])
- `https://mp4upload.com/embed-7l251136ll9r.html`
+ poster: `https://www4.mp4upload.com/i/00457/7l251136ll9r.jpg` (string, nullable)
+ stream (Stream, nullable)
+ updated: `2018-12-30T12:00:36.256000` (string, optional)
## Stream (object)
+ type: `Mp4Upload` (string, required)
+ url: `https://mp4upload.com/embed-wwfu2baijbw5.html` (string, required)
+ links (array[string], required)
- `https://www13.mp4upload.com:282/d/q2x3qydhz3b4quuoywuq2jkgkquu22zm3jnl5cygosqxspoouaepgm6r/video.mp4`
+ poster: `https://www13.mp4upload.com/i/00457/wwfu2baijbw5.jpg` (string, nullable)
+ updated: `2018-12-30T15:41:23.183197` (string, optional)
## SearchResult (object)
+ anime (Anime)
+ uid: `a-onepiece-en`
+ certainty: 0.6 (number) - Non-negative number denoting the certainty, that this result matches the provided query.
Depending on the search endpoint this may or may not be interpreted as a percentage.
However, bigger is always better.