Getting Started with icanhazdadjoke

← icanhazdadjoke

When to use this API

When you need a dad joke — a random one, a specific one by ID, or jokes matching a search term. This is the canonical dad joke API: 744 jokes, zero auth, one Accept header away from JSON. It's surprisingly useful as a lightweight "hello world" call in chat bots and icebreaker flows, and the search endpoint is the only programmatic way to find a joke about a specific topic in a curated, family-safe collection. For joke categories beyond dad-style puns (dark humor, programming jokes, one-liners), look elsewhere — this API is single-genre by design.

Fetching a random dad joke

"Tell me a joke." The root endpoint returns a random joke with no parameters. Set the Accept header to application/json — without it, you get plain text and lose the joke ID.

curl -H "Accept: application/json" "https://icanhazdadjoke.com/" | head -c 10000
{
  "id": "diGeqOfiqc",
  "joke": "What's E.T. short for? He's only got little legs.",
  "status": 200
}

The id field is a short alphanumeric string — persistent, shareable, and the key to the /j/{joke_id} endpoint. The status field mirrors the HTTP status code and is always 200 on success; it's redundant but convenient if you're parsing the body without checking HTTP headers. This particular joke is a good example of the genre's density: it works on two levels (the abbreviation "E.T." and the literal reading of "short") in under ten words, which is about the tightest construction you'll find in the 744-joke corpus.

What's E.T. short for? He's only got little legs.

Looking up a specific joke by ID

"I saw a joke about a poultry-geist — find it for me." If you have a joke ID (from a previous random fetch, a search result, or someone sharing a permalink), /j/{joke_id} retrieves that exact joke. No pagination, no search — just one joke.

curl -H "Accept: application/json" "https://icanhazdadjoke.com/j/HYTfVf21ob" | head -c 10000
{
  "id": "HYTfVf21ob",
  "joke": "What do you get if you cross a turkey with a ghost? A poultry-geist!",
  "status": 200
}

The response shape is identical to the random endpoint — same three fields, same structure. Joke IDs are stable: the same ID always returns the same joke. The API returns 404 with a JSON body { "status": 404, "message": "Joke not found" } for invalid IDs, which is cleaner than most joke APIs that silently return a random joke on miss. This makes /j/{joke_id} safe for bookmarking or deep-linking.

What do you get if you cross a turkey with a ghost? A poultry-geist!

Searching for jokes by keyword

"Find me a joke about cats." The search endpoint filters the corpus by term and paginates the results. Always set limit — the default is 20, which is manageable, but combining it with a term keeps the response tight.

curl -H "Accept: application/json" "https://icanhazdadjoke.com/search?term=cat&limit=5" | head -c 10000
{
  "current_page": 1,
  "limit": 5,
  "next_page": 2,
  "previous_page": 1,
  "results": [
    { "id": "0DdaxAX0orc", "joke": "I accidentally took my cats meds last night. Don't ask meow." },
    { "id": "B4fFKqf9ld", "joke": "What do you call a pile of cats? A meow-ntain." }
  ],
  "search_term": "cat",
  "status": 200,
  "total_jokes": 3,
  "total_pages": 1
}

The real story here is the pagination metadata: total_jokes tells you how many matches exist before you paginate, and total_pages tells you how many pages at your current limit. An empty search term returns the entire 744-joke corpus paginated — that's the firehose, and it's the fastest way to tank your context window. The previous_page value is 1 on the first page (not 0 or null), which is an unusual convention — page numbers are 1-indexed and the API never signals "no previous page" with a null. Also note the search is case-insensitive and matches substrings: "cat" matches "cats", "category", and "scattered".

I accidentally took my cats meds last night. Don't ask meow.

Pitfalls

One-line summary for the user

I can pull a random dad joke, look one up by ID, or search the 744-joke corpus by keyword from icanhazdadjoke.com — no auth required, just set the Accept header to JSON.