# Animechan

> Anime quotes with the character who said them and the show they are from, drawn from a curated collection of a few thousand lines across roughly four hundred and sixty series. Free and keyless.

App · Film, TV & Fandom · 8 actions. Web page: https://docs.lodol.com/docs/integrations/animechan

## Actions

### Check service status

Check whether Animechan is answering and how quickly, without failing the step when it is not. Put this in front of a workflow that would otherwise spend its daily request allowance discovering the service is down, and branch on 'ok'. It reports a throttle separately, so you can tell 'rate limited' from 'broken'.

**Inputs**: None.

**Outputs**

- `latency_ms` (number)
- `message` (text)
- `ok` (true/false)
- `rate_limited` (true/false)
- `status_code` (number)

**Example output**

```json
{
  "latency_ms": 742.0,
  "message": null,
  "ok": true,
  "rate_limited": false,
  "status_code": 200
}
```

### Find an anime

Search the catalogue by title and get back the shows that match, best first, each with how many quotes it has on record. The step to put in front of the others when all a workflow has is a title out of a form field. Matching here is better than the quote routes': it matches whole words and folds accents, so 'cowboy bebop' finds Cowboy Bebop and a title typed without its accents still lands. Alternate titles are searched too.

**Inputs**

- Title (`query`, text, required): The title, or part of it, to look for. Both the main and alternate titles are searched, so either spelling of a show works.
- Maximum results (`limit`, number): How many matches to return, from 1 to 100. Defaults to 10. 'total_matches' reports how many there were before this cut. From 1 to 100.

**Outputs**

- `catalogue_size` (number)
- `exact_match` (object)
- `match_count` (number)
- `matches` (list)
- `query` (text)
- `total_matches` (number)

**Example output**

```json
{
  "catalogue_size": 458,
  "exact_match": {
    "alt_name": "Cowboy Bebop",
    "anime_id": 52,
    "episode_count": 26,
    "mal_id": 1,
    "mal_url": "https://myanimelist.net/anime/1",
    "match_is_confident": true,
    "match_quality": "exact",
    "name": "Cowboy Bebop",
    "quote_count": 31
  },
  "match_count": 1,
  "matches": [
    {
      "alt_name": "Cowboy Bebop",
      "anime_id": 52,
      "episode_count": 26,
      "mal_id": 1,
      "mal_url": "https://myanimelist.net/anime/1",
      "match_is_confident": true,
      "match_quality": "exact",
      "name": "Cowboy Bebop",
      "quote_count": 31
    }
  ],
  "query": "Cowboy Bebop",
  "total_matches": 1
}
```

### Get a random anime quote

Get one random anime quote with the character who said it and the show it is from, ready to post. Narrow it to one anime or one character, or leave both empty to draw from the whole collection. Hand back the line you posted last time to avoid repeating it.

**Inputs**

- From this anime (`anime`, text): Only draw from this show. Leave empty to draw from any. Matching is loose and case-insensitive, so 'bebop' finds Cowboy Bebop. See 'Only exact matches' for when that goes wrong.
- From this character (`character`, text): Only draw from this character. Leave empty to draw from any. Short names are risky here: the API matches inside words, so 'Ken' also finds 'Kenshin'.
- Only exact matches (`require_exact_match`, true/false): Refuse anything that matched only as a substring. Animechan matches names inside words, so asking for the character 'Itachi' returns 'Hikaru Hitachiin' from Ouran High School Host Club: a success as far as the API is concerned, and the wrong show as far as anyone else is. Turn this on and a match that is not at least a whole word is dropped; leave it off and every result still carries 'match_quality' so a later step can decide.
- Don't repeat this quote (`avoid_content`, text): The text of a quote you have already posted. The draw is repeated up to 3 times to land on something else. If it keeps coming back, likely for a character with only one line on record, the quote is returned anyway with 'is_repeat' set rather than failing the step.

**Outputs**

- `avoided_content` (text)
- `is_repeat` (true/false)
- `quote` (object)
- `redraws` (number)
- `requested_anime` (text)
- `requested_character` (text)
- `require_exact_match` (true/false)

**Example output**

```json
{
  "avoided_content": null,
  "is_repeat": false,
  "quote": {
    "anime": {
      "alt_name": "Naruto",
      "anime_id": 178,
      "episode_count": null,
      "mal_id": null,
      "mal_url": null,
      "name": "Naruto",
      "quote_count": null
    },
    "anime_name": "Naruto",
    "character": {
      "character_id": 875,
      "name": "Naruto Uzumaki"
    },
    "character_name": "Naruto Uzumaki",
    "content": "Hard work is worthless for those that don't believe in themselves.",
    "match_is_confident": true,
    "match_quality": "exact"
  },
  "redraws": 0,
  "requested_anime": null,
  "requested_character": null,
  "require_exact_match": false
}
```

### Get quotes by anime

Get a page of quotes from one show, five at a time, which is all the API returns. Page through for more. Use this rather than drawing at random when you want a set from a known series, because it costs one request instead of one per quote.

**Inputs**

- Anime (`anime`, text, required): The show to take quotes from. Matching is loose and case-insensitive, so 'bebop' finds Cowboy Bebop. If all you have is a title typed by a user, run 'Find an anime' first and pass the name it confirms. An empty value is rejected: the API answers a blank name with random quotes rather than an error.
- Page (`page`, number): Which page of results to read, counting from 1. Five quotes come back per page, and the API publishes no way to ask for more. It sends no total, so 'has_more' reports only that a full page arrived. Page 0 is rejected here because the API answers it with an internal server error rather than saying what is wrong. From 1 to 10000.
- Only exact matches (`require_exact_match`, true/false): Refuse anything that matched only as a substring. Animechan matches names inside words, so asking for the character 'Itachi' returns 'Hikaru Hitachiin' from Ouran High School Host Club: a success as far as the API is concerned, and the wrong show as far as anyone else is. Turn this on and a match that is not at least a whole word is dropped; leave it off and every result still carries 'match_quality' so a later step can decide.

**Outputs**

- `dropped_loose_matches` (number)
- `has_more` (true/false)
- `page` (number)
- `past_last_page` (true/false)
- `quote_count` (number)
- `quotes` (list)
- `requested_anime` (text)
- `require_exact_match` (true/false)

**Example output**

```json
{
  "dropped_loose_matches": 0,
  "has_more": false,
  "page": 1,
  "past_last_page": false,
  "quote_count": 2,
  "quotes": [
    {
      "anime": {
        "alt_name": "Naruto",
        "anime_id": 178,
        "episode_count": null,
        "mal_id": null,
        "mal_url": null,
        "name": "Naruto",
        "quote_count": null
      },
      "anime_name": "Naruto",
      "character": {
        "character_id": 875,
        "name": "Naruto Uzumaki"
      },
      "character_name": "Naruto Uzumaki",
      "content": "Hard work is worthless for those that don't believe in themselves.",
      "match_is_confident": true,
      "match_quality": "exact"
    },
    {
      "anime": {
        "alt_name": "Naruto",
        "anime_id": 178,
        "episode_count": null,
        "mal_id": null,
        "mal_url": null,
        "name": "Naruto",
        "quote_count": null
      },
      "anime_name": "One Piece",
      "character": {
        "character_id": 876,
        "name": "Monkey D. Luffy"
      },
      "character_name": "Monkey D. Luffy",
      "content": "If you don't take risks, you can't create a future.",
      "match_is_confident": true,
      "match_quality": "exact"
    }
  ],
  "requested_anime": "Naruto",
  "require_exact_match": false
}
```

### Get quotes by character

Get a page of quotes from one character, five at a time. This is where Animechan's loose matching bites hardest, because character names are short: 'Itachi' also matches 'Hitachiin'. Turn on 'Only exact matches' when the name came from a user rather than from an earlier step.

**Inputs**

- Character (`character`, text, required): The character to take quotes from. Give the full name where you can, such as 'Naruto Uzumaki' rather than 'Naruto', because the API matches inside words and a short name collides with longer ones. An empty value is rejected.
- Page (`page`, number): Which page of results to read, counting from 1. Five quotes come back per page, and the API publishes no way to ask for more. It sends no total, so 'has_more' reports only that a full page arrived. Page 0 is rejected here because the API answers it with an internal server error rather than saying what is wrong. From 1 to 10000.
- Only exact matches (`require_exact_match`, true/false): Refuse anything that matched only as a substring. Animechan matches names inside words, so asking for the character 'Itachi' returns 'Hikaru Hitachiin' from Ouran High School Host Club: a success as far as the API is concerned, and the wrong show as far as anyone else is. Turn this on and a match that is not at least a whole word is dropped; leave it off and every result still carries 'match_quality' so a later step can decide.

**Outputs**

- `dropped_loose_matches` (number)
- `has_more` (true/false)
- `page` (number)
- `past_last_page` (true/false)
- `quote_count` (number)
- `quotes` (list)
- `requested_character` (text)
- `require_exact_match` (true/false)

**Example output**

```json
{
  "dropped_loose_matches": 0,
  "has_more": false,
  "page": 1,
  "past_last_page": false,
  "quote_count": 1,
  "quotes": [
    {
      "anime": {
        "alt_name": "Naruto",
        "anime_id": 178,
        "episode_count": null,
        "mal_id": null,
        "mal_url": null,
        "name": "Naruto",
        "quote_count": null
      },
      "anime_name": "Naruto",
      "character": {
        "character_id": 875,
        "name": "Naruto Uzumaki"
      },
      "character_name": "Naruto Uzumaki",
      "content": "Hard work is worthless for those that don't believe in themselves.",
      "match_is_confident": true,
      "match_quality": "exact"
    }
  ],
  "requested_character": "Naruto Uzumaki",
  "require_exact_match": false
}
```

### Get several random quotes

Get several different anime quotes at once, up to 10. No quote is drawn twice in the same batch. The API returns one random quote per request, so a batch of five spends five of the hundred requests this service allows per day, which is exactly why the ceiling is low. Narrow to one anime or character if you want a themed set.

**Inputs**

- Number of quotes (`count`, number): How many quotes to draw, from 1 to 10. Defaults to 3. Each one is a separate request against the daily allowance. Fewer may come back than asked for if the pool is small: compare 'quote_count' with 'requested_count'. From 1 to 10.
- From this anime (`anime`, text): Only draw from this show. Leave empty to draw from any.
- From this character (`character`, text): Only draw from this character. Leave empty to draw from any.

**Outputs**

- `quote_count` (number)
- `quotes` (list)
- `requested_anime` (text)
- `requested_character` (text)
- `requested_count` (number)

**Example output**

```json
{
  "quote_count": 3,
  "quotes": [
    {
      "anime": {
        "alt_name": "Naruto",
        "anime_id": 178,
        "episode_count": null,
        "mal_id": null,
        "mal_url": null,
        "name": "Naruto",
        "quote_count": null
      },
      "anime_name": "Naruto",
      "character": {
        "character_id": 875,
        "name": "Naruto Uzumaki"
      },
      "character_name": "Naruto Uzumaki",
      "content": "Hard work is worthless for those that don't believe in themselves.",
      "match_is_confident": true,
      "match_quality": "exact"
    },
    {
      "anime": {
        "alt_name": "Naruto",
        "anime_id": 178,
        "episode_count": null,
        "mal_id": null,
        "mal_url": null,
        "name": "Naruto",
        "quote_count": null
      },
      "anime_name": "One Piece",
      "character": {
        "character_id": 876,
        "name": "Monkey D. Luffy"
      },
      "character_name": "Monkey D. Luffy",
      "content": "If you don't take risks, you can't create a future.",
      "match_is_confident": true,
      "match_quality": "exact"
    },
    {
      "anime": {
        "alt_name": "Cowboy Bebop",
        "anime_id": 52,
        "episode_count": null,
        "mal_id": null,
        "mal_url": null,
        "name": "Cowboy Bebop",
        "quote_count": null
      },
      "anime_name": "Cowboy Bebop",
      "character": {
        "character_id": 311,
        "name": "Spike Spiegel"
      },
      "character_name": "Spike Spiegel",
      "content": "Whatever happens, happens.",
      "match_is_confident": true,
      "match_quality": "exact"
    }
  ],
  "requested_anime": null,
  "requested_character": null,
  "requested_count": 3
}
```

### Get the quote of the day

Pick one quote for a given day and get the same one back every time you ask. A random draw cannot do this: two steps running the same morning would post different quotes, and re-running yesterday would not reproduce yesterday's. Give each workflow its own seed if two of them share a day and should not share a quote.

**Inputs**

- Date (`date`, date): The day to pick for, as YYYY-MM-DD. Leave empty for today in UTC. UTC rather than local time so a scheduled run and a re-run of it agree on which day it is.
- Seed (`seed`, text): Any text that makes this workflow's pick its own. Two workflows with different seeds get different quotes on the same day, and each still gets the same quote all day. Leave empty to share the default pick.

**Outputs**

- `anime` (object)
- `date` (text)
- `pool_size` (number)
- `quote` (object)
- `seed` (text)

**Example output**

```json
{
  "anime": {
    "alt_name": "Cowboy Bebop",
    "anime_id": 52,
    "episode_count": 26,
    "mal_id": 1,
    "mal_url": "https://myanimelist.net/anime/1",
    "name": "Cowboy Bebop",
    "quote_count": 31
  },
  "date": "2026-03-20",
  "pool_size": 458,
  "quote": {
    "anime": {
      "alt_name": "Cowboy Bebop",
      "anime_id": 52,
      "episode_count": null,
      "mal_id": null,
      "mal_url": null,
      "name": "Cowboy Bebop",
      "quote_count": null
    },
    "anime_name": "Cowboy Bebop",
    "character": {
      "character_id": 311,
      "name": "Spike Spiegel"
    },
    "character_name": "Spike Spiegel",
    "content": "Whatever happens, happens.",
    "match_is_confident": true,
    "match_quality": "exact"
  },
  "seed": null
}
```

### List anime

List the shows Animechan carries, a hundred per page, with how many quotes each has and its MyAnimeList id where one is known. This is the only route that reports a total and a page count, so it is the one to loop over to walk the whole catalogue.

**Inputs**

- Page (`page`, number): Which page of the catalogue to read, counting from 1. A hundred shows come back per page. Unlike the quote routes this one reports 'total' and 'total_pages', so a loop can tell when it is done. From 1 to 10000.

**Outputs**

- `anime` (list)
- `anime_count` (number)
- `has_more` (true/false)
- `page` (number)
- `page_size` (number)
- `total` (number)
- `total_pages` (number)

**Example output**

```json
{
  "anime": [
    {
      "alt_name": "Cowboy Bebop",
      "anime_id": 52,
      "episode_count": 26,
      "mal_id": 1,
      "mal_url": "https://myanimelist.net/anime/1",
      "name": "Cowboy Bebop",
      "quote_count": 31
    },
    {
      "alt_name": "Naruto",
      "anime_id": 178,
      "episode_count": 220,
      "mal_id": 20,
      "mal_url": "https://myanimelist.net/anime/20",
      "name": "Naruto",
      "quote_count": 137
    }
  ],
  "anime_count": 2,
  "has_more": true,
  "page": 1,
  "page_size": 100,
  "total": 458,
  "total_pages": 5
}
```
