WAIFU.IM is an easy to use api that allows you to get waifu pictures from an archive of over 4000 images and multiple tags!
https://api.waifu.im/
You can specify which version of the API you want to use by placing it in the Accept-Version header. If the value doesn't match any version the latest is used. We highly recommend you to use it since it will prevent your app to break if a new version with breaking change is developed. You can check which version you are using in the Version response header.
The latest version of the API is v5.
Note: this rate limit only apply for api.waifu.im domain.
The rate limit is 1 request every 200 milliseconds. If you go up to this value the request will be put in a queue (the size is 10). If the queue is full, the server will answer with a 429 status code.
You can check the Retry-After header to get the time to wait for (in seconds) before making another request.
Here you can find the GitHub organization and some recommended wrappers.
• GitHub
• Python wrapper
• C# wrapper
Images are classified by a tag system and can have multiple tags!
There are versatile tags that can describe both safe and lewd images and specially nsfw tags that only describe lewd images.
If no tag filtering is requested, the default tag, waifu, will be included. You can find a list of available tags here or below.
Path | Request type |
---|---|
/tags | GET |
To get more information about the tags please take a look at the query strings.
Name | Required | Type | Behavior |
---|---|---|---|
full | No | Boolean | Returns more information about the tags, such as a description. Default is false |
Example JSON response of an API error.
{
"detail": "Description / Details"
}
You can get images randomly or by tag
Path | Request type |
---|---|
/search | GET |
To filter by tag or by nsfw images please take a look at the query strings.
Example JSON response of a /search call
{
"images": [
{
"signature": "58e6f0372364abda",
"extension": ".png",
"image_id": 8108,
"favorites": 1,
"dominant_color": "#bbb7b2",
"source": "https://www.patreon.com/posts/persephone-78224476",
"artist": {
"artist_id": 1,
"name": "fourthwallzart",
"patreon": null,
"pixiv": null,
"twitter": "https://twitter.com/4thWallzArt",
"deviant_art": "https://www.deviantart.com/4thwallzart"
},
"uploaded_at": "2023-05-03T18:40:04.381354+02:00",
"liked_at": null,
"is_nsfw": false,
"width": 1536,
"height": 2304,
"byte_size": 3299586,
"url": "https://cdn.waifu.im/8108.png",
"preview_url": "https://www.waifu.im/preview/8108/",
"tags": [
{
"tag_id": 12,
"name": "waifu",
"description": "A female anime/manga character.",
"is_nsfw": false
}
]
}
]
}
Name | Required | Type | Behavior |
---|---|---|---|
included_tags | No | String Array | Force the API to return images with at least all the provided tags |
excluded_tags | No | String Array | Force the API to return images without any of the provided tags |
is_nsfw | No | Strict Boolean or String | Force or exclude lewd files (only works if included_tags only contain versatile tags and no nsfw only tag). You can provide 'null' to make it be random. Default is false |
gif | No | Boolean | Force or prevent the API to return .gif files |
order_by | No | String | Options are: FAVORITES, UPLOADED_AT, RANDOM. Default is RANDOM |
orientation | No | String | Options are: LANDSCAPE, PORTRAIT, RANDOM. Default is RANDOM |
height | No | String (Operator, Integer) | Filter images by height (in pixels). Accepted operators: <=, >=, >, <, !=, =. e.g. >=2000 |
width | No | String (Operator, Integer) | Filter images by width (in pixels). Accepted operators: <=, >=, >, <, !=, =. e.g. >=2000 |
byte_size | No | String (Operator, Integer) | Filter images by byte size. Accepted operators: <=, >=, >, <, !=, =. e.g. >=2000 |
many | No | Boolean | Return an array of 30 files if true |
full | No | Boolean | Returns the full result without any limit (admins only) |
included_files | No | String Array | Force the API to provide only the specified file IDs or signatures |
excluded_files | No | String Array | Force the API to not list the specified file IDs or signatures |
To take in an array of values, provide the query string again with different values
A python example with some query strings.
import aiohttp
# In this example aiohttp is used.
# This needs to be used in an async function.
# This is simply for demonstrative purposes, you can use
# any library for this.
# The only supported headers are User-Agent and Authorization
# Please change the user-agent as it's useful for identification purposes.
# This endpoint does not require a token but some others do.
headers = {'Accept-Version':'v5', 'User-Agent': f'aiohttp/{aiohttp.__version__}; YourAppName'}
# Here let's say you want to exclude some images, disable gifs and request only safe pictures
# The url is written in multiple lines for readability purposes, but it is equal to:
# https://api.waifu.im/search/?excluded_files=3867126be8e260b5&excluded_files=3133&gif=false&excluded_tags=maid&excluded_tags=oppai&is_nsfw=false
# You can also provide params as a dict or a list of tuple with the 'params' kwarg
url = "https://api.waifu.im/search/?excluded_files=4401" \
"&excluded_files=3133" \
"&gif=false" \
"&excluded_tags=maid" \
"&excluded_tags=oppai" \
"&is_nsfw=false"
# Usually you would create a session and access it when needed.
session = aiohttp.ClientSession()
async with session.get(url, headers=headers) as resp:
api = await resp.json()
if resp.status in {200, 201}:
url = api['images'][0]['url']
# Do whatever you want with the image url.
else:
error = api['detail']
# Do whatever you want with the error description.
This part isn't directly related to the API and the base url is not the same. This will allow you to generate a link asking a user that will click on it, permissions over his Waifu.im account (you also can do the opposite with revoke).
This will be useful if you want to use the user_id query string when dealing with favorites.
URI | Request type |
---|---|
https://www.waifu.im/authorization/ | GET |
https://www.waifu.im/authorization/revoke/ | GET |
Name | Required | Type | Behavior |
---|---|---|---|
user_id | Yes | Integer | The discord user ID of the user that will receive the permissions |
permissions | Yes | String Array | The permissions that will be asked for. Available permissions are 'view_favorites' and 'manage_favorites' |
To take in an array of values, provide the query string again with different values
You can create your own gallery composed of your favorite images that you can look at conveniently. You can access your favorite images through the website or the API.
Path | Request type |
---|---|
/fav | GET |
This requires a token and you will need to place it in the Authorization header, see an example here.
Example JSON response of a /fav call
{
"images": [
{
"signature": "58e6f0372364abda",
"extension": ".png",
"image_id": 8108,
"favorites": 1,
"dominant_color": "#bbb7b2",
"source": "https://www.patreon.com/posts/persephone-78224476",
"artist": {
"artist_id": 1,
"name": "fourthwallzart",
"patreon": null,
"pixiv": null,
"twitter": "https://twitter.com/4thWallzArt",
"deviant_art": "https://www.deviantart.com/4thwallzart"
},
"uploaded_at": "2023-05-03T18:40:04.381354+02:00",
"liked_at": "2023-05-03T18:40:48.636703+02:00",
"is_nsfw": false,
"width": 1536,
"height": 2304,
"byte_size": 3299586,
"url": "https://cdn.waifu.im/8108.png",
"preview_url": "https://www.waifu.im/preview/8108/",
"tags": [
{
"tag_id": 12,
"name": "waifu",
"description": "A female anime/manga character.",
"is_nsfw": false
}
]
}
]
}
Name | Required | Type | Behavior |
---|---|---|---|
user_id | No | Integer | The discord user ID you want to see favorites for (this work only if the user has granted you permission) |
included_tags | No | String Array | Force the API to return images with at least all the provided tags |
excluded_tags | No | String Array | Force the API to return images without any of the provided tags |
is_nsfw | No | Strict Boolean or String | Force or exclude lewd files (only works if included_tags only contain versatile tags and no nsfw only tag). You can provide 'null' to make it be random. Default is false |
gif | No | Boolean | Force or prevent the API to return .gif files |
order_by | No | String | Options are: FAVORITES, UPLOADED_AT, LIKED_AT, RANDOM. Default is LIKED_AT |
orientation | No | String | Options are: LANDSCAPE, PORTRAIT, RANDOM. Default is RANDOM |
height | No | String (Operator, Integer) | Filter images by height (in pixels). Accepted operators: <=, >=, >, <, !=, =. e.g. >=2000 |
width | No | String (Operator, Integer) | Filter images by width (in pixels). Accepted operators: <=, >=, >, <, !=, =. e.g. >=2000 |
byte_size | No | String (Operator, Integer) | Filter images by byte size. Accepted operators: <=, >=, >, <, !=, =. e.g. >=2000 |
many | No | Boolean | Return an array of 30 files if true |
full | No | Boolean | Returns the full result without any limit (admins only) |
included_files | No | String Array | Force the API to provide only the specified file IDs or signatures |
excluded_files | No | String Array | Force the API to not list the specified file IDs or signatures |
To take in an array of values, provide the query string again with different values
In this example we want to get all the safe images with the waifu tag programmatically (even thought we could use included_tags query string). We also tell the API to returns only landscape pictures.
import aiohttp
token="eyJpZCI6NTA4MzQ2OTc4Mjg4MjcxMzYwLCJzZWNyZXQiOiJyb3AtekZIeE12bll4ZyJ9.89aLylZeRcIcYDjfg6E01iPRCqI"
# Please do change the user agent, it's useful for identification purpose.
headers= {'Accept-Version':'v5', 'User-Agent':f'aiohttp/{aiohttp.__version__}; YourAppName','Authorization':f"Bearer {token}"}
def has_waifu_tag(image):
for t in image["tags"]:
return t["name"] == "waifu" and not image["is_nsfw"]
# Do not open a new session everytime like here, save it
async with aiohttp.ClientSession() as cs:
# In this example we get all the picture with a landscape orientation in the user favorites
async with cs.get(f"https://api.waifu.im/fav?orientation=LANDSCAPE",headers=headers) as rep:
api = await rep.json()
if rep.status in {200, 201}:
# The filter() function extracts elements from an iterable (list, tuple etc.) for which a function returns True
waifu = list(filter(has_waifu_tag,rep["images"]))
# Do whatever you want with the waifu tag pictures.
# As mentioned before we could just have add '&included_tags=waifu'
else:
error = api["detail"]
#do whatever you want with the error message.
You can set or unset your favorite images in addition to being able to view them
You can add a favorite image or remove one by ID. You can also toggle favoriting an image by ID meaning it will be either added or removed depending on if it is in your favorites.
Path | Request type |
---|---|
/fav/insert | POST |
/fav/delete | DELETE |
/fav/toggle | POST |
This requires a token and you will need to place it in the Authorization header, see an example here.
Example JSON response of a /fav/insert, /fav/delete or /fav/toggle call
{
"state": "DELETED" or "INSERTED" depending on the action done
}
Name | Required | Type | Behavior |
---|---|---|---|
user_id | No | Integer | The discord user ID you want to modify favorites for (this works only if the user has granted you permission) |
image_id | Yes | Integer | The ID (only) of the image that you want to add, remove or toggle from the user favorites |