☰ Menu JokeAPI Documentation v2.1.5 (Changelog)
GitHub • Legal Stuff • Author

By using this website and API you are agreeing to the privacy policy

(Click here to get more information on what data JokeAPI collects) I agree
JokeAPI is a RESTful API that serves uniformly and well formatted jokes.
It can be used without any API token, membership, registration or payment.
It supports a variety of filters that can be applied to get just the right jokes you need.
The usage is very simple and similar to other RESTful APIs and requires only basic knowledge of HTTP/HTTPS requests and JSON, XML or YAML.

If you come across a term you don't understand, you can try opening the menu and clicking on the section "Terminology".
JokeAPI currently serves 220 jokes. To submit a new joke, please click here.

If you want to report a bug or an illegal joke, please use the GitHub issue tracker.
If you want to contribute to JokeAPI, please read the Contributing Guide.

If you are new to JokeAPI, please start by reading the Getting Started Guide

Note: JokeAPI has been a target of DoS attacks in the past, which is why there is now a limit of 60 requests per minute and why joke submissions are manually curated.
Select category / categories:
Select flags to blacklist:
Select response format:
Select at least one joke type:
Search for a joke that
contains this search string:
Search for a joke
in this ID range:
(optional)    From: To:

URL: (Loading...)
(Set parameters and click "Send Request" above)
JokeAPI doesn't require any API token, authorization or payment to work, although there is a hard limit of 60 requests per minute due to some DoS attacks I have been getting.
To start using JokeAPI, you can do one of these two things:
If you know any good jokes and want to add them to JokeAPI, please click here.
If you need any help, feel free to join my Discord server.
A wrapper is generally a library that wraps around a certain function to make your life easier.
In the case of RESTful APIs like JokeAPI, a wrapper library makes it so you can use functions and objects to communicate with the API and the wrapper will do all the HTTP requests for you in the background.
The following is a list of officially supported JokeAPI wrappers:

Language Wrapper Author
Rust Sv443_JokeAPI Rust Crate canarado
Python Sv443s JokeAPI Python Wrapper thenamesweretakenalready

Payload Preview:
URL parameters are like the settings or the configuration of an HTTP request.
The parameters need to be prefixed by a single question mark (?) and separate key/value pairs need to be delimited from another by an ampersand (&). Keys are separated from values with an equals sign (=).
Example: https://example.org/some/page?key1=foo&key2=bar&key3=baz ... (yellow = key/value pair)
Format: This parameter is global - it can be used on every single endpoint of JokeAPI (excluding the documentation and static content).
It is used to change the response format from the default (JSON) to (Loading...), depending on what you need.
If the format parameter is invalid or not specified at all, the default value of JSON will be used.
Available formats are (Loading...)

Example 1 (click to view) URL: https://sv443.net/jokeapi/v2/joke/Any?format=xml

<data> <category>Programming</category> <type>single</type> <joke>// This line doesn't actually do anything, but the code stops working when I delete it.</joke> <flags> <nsfw>false</nsfw> <religious>false</religious> <political>false</political> <racist>false</racist> <sexist>false</sexist> </flags> <id>12</id> </data>

Example 2 (click to view) URL: https://sv443.net/jokeapi/v2/joke/Any?format=txt

How many programmers does it take to screw in a light bulb? None. It's a hardware problem.

Blacklist Flags: This parameter can only be used on the "joke" endpoint.
If it is used, jokes that match the specified flag(s) will not be served (what is a flag?).
If you want to use multiple flags, separate them with a comma (,) or a plus sign (+).
These are all the available flags: (Loading...)

Example 1 (click to view) URL: https://sv443.net/jokeapi/v2/joke/Any?blacklistFlags=nsfw
Using the above URL makes sure you don't get any jokes that are not safe for work.

Example 2 (click to view) URL: https://sv443.net/jokeapi/v2/joke/Any?blacklistFlags=nsfw,racist,sexist
Using the above URL makes sure you don't get any jokes that are not safe for work, racist and sexist.

Joke Type: This parameter can only be used on the "joke" endpoint.
If it is set, you will only receive jokes with the specified joke type (what is a joke type?).
If it is not set or set to an invalid value, you will receive jokes of both types.
Available types are: single, twopart

Example (click to view) URL: https://sv443.net/jokeapi/v2/joke/Any?type=twopart

{ "category": "Programming", "type": "twopart", "setup": "What is a dying programmer's last program?", "delivery": "Goodbye, world!", "flags": { "nsfw": false, "religious": false, "political": false, "racist": false, "sexist": false }, "id": 58 }

(no jokes with type "single" will be served)

Contains: This parameter can only be used on the "joke" endpoint.
If this parameter is specified, only jokes that contain the value of this parameter will be served (case insensitive).
IMPORTANT: If the value of this parameter contains special characters, it needs to be percent-encoded according to the URI standard (MDN Reference), otherwise you might get an error or a wrong response.

Example (click to view) URL: https://sv443.net/jokeapi/v2/joke/Any?contains=C%23 (%23 = pound character / hashtag / # - so the thing searched for here is "C#")

{ "category": "Programming", "type": "twopart", "setup": "Why do programmers wear glasses?", "delivery": "Because they need to C#", "flags": { "nsfw": false, "religious": false, "political": false, "racist": false, "sexist": false }, "id": 51 }

ID Range: This parameter can only be used on the "joke" endpoint.
If it is used, you will only get jokes that are inside the specified range of IDs.
The lower and upper boundary of the ID range needs to be delimited with a minus (-), comma (,) or a plus sign (+).
If you only want to get a single joke by its ID, you can also ignore the delimiter and just use the single ID as the value for this parameter.
As there are currently 220 jokes, the ID range can be any range from 0 - 219

Example 1 (click to view) URL: https://sv443.net/jokeapi/v2/joke/Any?idRange=0-55
Using the above URL will make JokeAPI only serve you jokes that are inside the ID range of 0 to 55.

Example 2 (click to view) URL: https://sv443.net/jokeapi/v2/joke/Any?idRange=33
Using the above URL will make JokeAPI only serve you the joke with the ID 33 (provided there are no other filters that are blacklisting that joke).
In JokeAPI all response data, no matter from which endpoint will have a boolean "error" parameter.
Usually, it is set to false, which means there was no error in your request or on the server.
If the "error" parameter is set to true though, there was an error and JokeAPI will add an "internalError", "message", "causedBy", "additionalInfo" and "timestamp" parameter.

The "internalError" parameter will be set to false, if the error was due to a malformed or failed request and it will be true, if the error is JokeAPI's fault.
The "message" parameter will contain a short version of the error message and the "timestamp" parameter will contain a 13-character Unix timestamp.
The "causedBy" parameter is an array of possible causes of this error and the "addidionalInfo" parameter contains a more descriptive error message.

You can view an example of an error, where an invalid category was used, just below this paragraph.
Together with the HTTP status code, which will also be set according to the type of error, these parameters can be used to improve error handling massively from what was the error system in previous versions of JokeAPI.

Example Error:
{ "error": true, "internalError": false, "code": 106, "message": "No matching joke found", "causedBy": [ "No jokes were found that match your provided filter(s)" ], "additionalInfo": "The specified category is invalid - Got: \"foo\" - Possible categories are: \"Any, Miscellaneous, Programming, Dark\" (case insensitive)", "timestamp": 1579170794412 }

Status Codes:
Code Name Description
200 Ok The request was accepted and processed successfully and the respose text contains the requested data or a status message
201 Created The joke submission is formatted correctly and was accepted and successfully saved
400 Bad Request The request you have sent to JokeAPI is formatted incorrectly and cannot be processed
403 Forbidden You have been added to the blacklist due to malicious behavior and are not allowed to send requests to JokeAPI anymore
404 Not Found The URL you have requested couldn't be found
413 Payload Too Large The payload data sent to the server exceeds the maximum size of 5120 bytes
414 URI Too Long The URL exceeds the maximum length of 250 characters
429 Too Many Requests You have exceeded the limit of 60 requests per minute and have to wait a bit until you are allowed to send requests again
500 Internal Server Error There was a general internal error within JokeAPI. You can get more info from the properties in the response text
523 Origin Unreachable My server is temporarily offline due to maintenance or a dynamic IP update. Please be patient in this case.

SuccessClient ErrorServer Error An endpoint is an access point to send the HTTP requests to and get your response.
JokeAPI offers these following endpoints:

Get Joke: GET https://sv443.net/jokeapi/v2/joke/[Category/-ies]

This endpoint is the one you want to call to get a joke.
A valid joke category or multiple joke categories, delimited with a comma, plus or minus character (, + -) must be provided in the URL.
These are all the available categories: (Loading...)
To see how this URL is built with certain parameters set, visit the "Try It" section.
Example - click to view https://sv443.net/jokeapi/v2/joke/Programming,Miscellaneous?format=xml&blacklistFlags=nsfw,sexist&type=single

Will give a joke from either the Programming or the Miscellaneous category, with the payload format XML,
with the joke type "single", while also preventing all jokes that are potentially not safe for work and sexist from being served.

Supported URL parameters:
(More info on filtering parameters)

Info: GET https://sv443.net/jokeapi/v2/info

This endpoint provides some information on JokeAPI:
- The version number
- The amount of jokes
- All the available categories, flags, types and formats
- A 13-character UNIX timestamp
- The URL to a joke submission form
- The minimum and maximum values of an ID range
- A string with some information, like a message of the day

Supported URL parameters:

Categories: GET https://sv443.net/jokeapi/v2/categories

This endpoint returns a list / an array of all available joke categories and a 13-character UNIX timestamp.

Supported URL parameters:

Flags: GET https://sv443.net/jokeapi/v2/flags

This endpoint returns a list / an array of all available blacklist flags and a 13-character UNIX timestamp.

Supported URL parameters:

Formats: GET https://sv443.net/jokeapi/v2/formats

This endpoint returns a list / an array of all available response formats and a 13-character UNIX timestamp.

Supported URL parameters:

Ping: GET https://sv443.net/jokeapi/v2/ping

This endpoint returns a parameter named "ping" that contains the word "Pong!" and a 13-character UNIX timestamp.
It is intended for external uptime monitoring but you can also use it if you want to.

Supported URL parameters:

Endpoints: GET https://sv443.net/jokeapi/v2/endpoints

This endpoint returns a list / an array of all available endpoints, their usage (method, url and supported parameters) and a short description each.

Supported URL parameters:

Submit Joke: PUT https://sv443.net/jokeapi/v2/submit

This endpoint is used to submit a joke to be reviewed and added to JokeAPI's official jokes.
If you instead just want to manually submit a joke, please click here.
The payload needs to be sent as JSON. Different formats are not allowed here.
The request payload has to follow the same object structure that the jokes are served in when using the "joke" endpoint.

Make sure to add a "formatVersion" property, which just contains the current joke format version (2).
This is needed since there were a few changes to the object format since the previous versions and this ensures consistency.

The joke category has to be any valid category, excluding "Any".
If the joke type is set to "single", the properties "setup" and "delivery" will need to be omitted and the joke is to be put in the "joke" property.
If the joke type is set to "twopart", the "joke" property is to be replaced with the properties "setup" and "delivery".
The "flags" property needs to be an object that contains the boolean properties "nsfw", "religious", "political", "racist" and "sexist". These need to be set accordingly.
The joke ID doesn't need to be provided as it will be automatically assigned to the joke.

If the joke is valid and the server accepted the submission, you will get a response with the status code 201.

Example Payload:
{ "formatVersion": 2, "category": "Miscellaneous", "type": "single", "joke": "A horse walks into a bar...", "flags": { "nsfw": true, "religious": false, "political": true, "racist": false, "sexist": false } }

Supported URL parameters:

Click here to see how the server responds to a joke submission Server Response:
{ "error": false, "message": "Joke submission was successfully saved. It will soon be checked out by the author.", "submission": { "formatVersion": 2, "category": "Miscellaneous", "type": "single", "joke": "A horse walks into a bar...", "flags": { "nsfw": true, "religious": false, "political": true, "racist": false, "sexist": false } }, "timestamp": 1579685839560 }

I created JokeAPI with the main purpose of it having many versatile filtering options as other APIs didn't offer this amount of customization.
In this section you will learn how the filtering works.

There are six different filtering methods in JokeAPI:
JokeAPI has a way of whitelisting certain clients. This is achieved through an API token.
At the moment, you will only receive one of these tokens temporarily if something breaks or if you are a business and need more than 60 requests per minute.
If you do end up receiving a token, using it is as easy as adding an Authorization header with the actual token as its value.
You will receive a response header called Token-Valid which will contain the number 1 if the token is valid.
If the token is invalid, the Token-Valid header will be set to 0 and JokeAPI will treat your request as if you didn't supply a token in the first place. These are some examples in some commonly used languages to show you how you could implement JokeAPI:

Node.js (click to show) Node.js:
const https = require("https"); // Native module, no need to explicitly install const baseURL = "https://sv443.net/jokeapi/v2"; const categories = ["Programming", "Miscellaneous"]; const params = [ "blacklistFlags=nsfw,religious,racist", "idRange=0-100" ]; https.get(`${baseURL}/joke/${categories.join(",")}?${params.join("&")}`, res => { console.log("\n"); res.on("data", chunk => { // On data received, convert it to a JSON object let randomJoke = JSON.parse(chunk.toString()); if(randomJoke.type == "single") { // If type == "single", the joke only has the "joke" property console.log(randomJoke.joke); console.log("\n"); } else { // If type == "twopart", the joke has the "setup" and "delivery" properties console.log(randomJoke.setup); setTimeout(() => { console.log(randomJoke.delivery); console.log("\n"); }, 3000); } }); res.on("error", err => { // On error, log to console console.error(`Error: ${err}`); }); });

Web-JavaScript (click to show) Web-JS:
var baseURL = "https://sv443.net/jokeapi/v2"; var categories = ["Programming", "Miscellaneous"]; var params = [ "blacklistFlags=nsfw,religious,racist", "idRange=0-100" ]; var xhr = new XMLHttpRequest(); xhr.open("GET", baseURL + "/joke/" + categories.join(",") + "?" + params.join("&")); xhr.onreadystatechange = function() { if(xhr.readyState == 4 && xhr.status < 300) // readyState 4 means request has finished + we only want to parse the joke if the request was successful (status code lower than 300) { var randomJoke = JSON.parse(xhr.responseText); if(randomJoke.type == "single") { // If type == "single", the joke only has the "joke" property alert(randomJoke.joke); } else { // If type == "single", the joke only has the "joke" property alert(randomJoke.setup); alert(randomJoke.delivery); } } else if(xhr.readyState == 4) { alert("Error while requesting joke.\n\nStatus code: " + xhr.status + "\nServer response: " + xhr.responseText); } }; xhr.send();

C# (click to show) C#:
using System; using System.IO; using System.Net; using System.Web.Script.Serialization; // Requires you to include the assembly "System.Web.Extensions" in your project private void getJoke() { string baseURL = "https://sv443.net/jokeapi/v2"; string[] categories = { "Programming", "Miscellaneous" }; string[] parameters = { "blacklistFlags=nsfw,religious,racist", "idRange=0-100" }; // Create request and wait for response WebRequest request = WebRequest.Create($"{baseURL}/joke/{string.Join(",", categories)}?{string.Join("&", parameters)}"); WebResponse response = request.GetResponse(); using (Stream dataStream = response.GetResponseStream()) { // Convert the stream to a string StreamReader reader = new StreamReader(dataStream); string responseFromServer = reader.ReadToEnd(); // Deserialize the string into an object of the Joke class JavaScriptSerializer ser = new JavaScriptSerializer(); Joke randomJoke = ser.Deserialize(responseFromServer); if (randomJoke.type == "single") { // If type == "single", the joke only has the "joke" property Console.WriteLine(randomJoke.joke); } else { // If type == "twopart", the joke has the "setup" and "delivery" properties Console.WriteLine(randomJoke.setup); System.Threading.Thread.Sleep(3000); Console.WriteLine(randomJoke.delivery); } } // Close the request response.Close(); } public class Joke { public string type { get; set; } public string joke { get; set; } public string setup { get; set; } public string delivery { get; set; } public int id { get; set; } public Flags flags { get; set; } } public class Flags { public bool nsfw { get; set; } public bool religious { get; set; } public bool political { get; set; } public bool racist { get; set; } public bool sexist { get; set; } }

You might come across some terms in this documentation you don't understand. This section teaches you what those terms mean.
Categories: JokeAPI has a first, coarse filter that just categorizes the jokes depending on what the joke is about or who the joke is directed at.
A joke about programming will be in the "Programming" category, dark humor will be in the "Dark" category and so on.
If you want jokes from all categories, you can instead use "Any", which will make JokeAPI randomly choose a category.

These are all the available categories: (Loading...)
To set the category you want, you need to add it to the URL path, just after the "/joke" endpoint, like this: https://sv443.net/jokeapi/v2/joke/Programming (Blacklist-) Flags: Blacklist Flags (or just "Flags") are a more fine layer of filtering.
Multiple flags can be set on each joke and they tell you something about the offensiveness of each joke.
You can tell JokeAPI to not give you jokes that have the specified flags by using the ?blacklistFlags URL parameter.

These are all the available flags: (Loading...)
(Response-) Formats: Response Formats (or just "Formats") are a way to get your data in a different file format.
Maybe you are using some other code that only accepts XML. In that case, JokeAPI is able to convert the JSON-formatted joke to XML for you.
You can tell JokeAPI which file format to respond with by using the ?format URL parameter.

These are all the available formats: (Loading...)
Joke Type: Each joke comes with one of two types: single or twopart.
If a joke is of type "twopart", it has a setup string and a delivery string, which are both part of the joke.
They are separated because you might want to present the users the delivery after a timeout or in a different section of the UI.
A joke of type "single" only has a single string, which is the entire joke.
If you only want one type of joke, you can use the ?type URL parameter.

These are the available types: single, twopart
Search String: If the search string filter is used, only jokes that contain the specified string will be returned.
You can specify this search string by using the ?contains URL parameter.
IMPORTANT: If the value of this parameter contains special characters, it needs to be percent-encoded according to the URI standard (MDN Reference), otherwise you might get an error or a wrong response.
ID Range: If this filter is used, you will only get jokes that are within the provided range of IDs.
You don't necessarily need to provide an ID range though, a single ID will work just fine as well.
Example: an ID range of 0-9 will mean you will only get one of the first 10 jokes, while an ID range of 5 will mean you will only get the 6th joke.
You can set the ID range by using the ?idRange URL parameter.
As there are currently 220 jokes, the ID range can be anywhere in the range of 0 to 219
JokeAPI is licensed under the MIT License.
Before modifying and / or redistributing the source code, please take two minutes to read the license text.
You can view the full license text by clicking here.

JokeAPI has to collect some anonymized data to work.
To view a list with details, please click here.
To view the privacy policy, please click here.
To view the site notice / imprint, click here.

I will hereby not claim any legal responsibility or liability for JokeAPI and the jokes it serves (especially those from the "Dark" category).
Whether it is used maliciously or breaks something in your project or someone gets offended by a joke, I can't be held accountable.
Additionally, I will only be able to provide security updates for a small selection of versions, a list of which you can find here.
I am doing my best to ensure security and stability but there's only so much a single developer can do.
Please report any issue that may arise to the GitHub issue tracker and I will try my best to fix it as soon as possible.
If you want to contact me, you can join my Discord server (fastest way to contact me) or send me an E-Mail at [email protected]

JokeAPI uses these third party fonts on its documentation page:

JokeAPI uses these libraries:

These are the packages JokeAPI depends on (excluding dependencies of dependencies and devDependencies):
These are some of the projects that depend on JokeAPI: (Contact me to get your project added here)

Information Try it out Getting Started API Wrappers Submit a Joke URL Parameters Errors
Filtering Jokes API Tokens Examples
Legal Stuff Dependents