When to use this skill
When the user asks for a joke, a dad joke, a pun, or wants to find a joke about a specific topic like "cats" or "food." icanhazdadjoke.com is a curated, family-safe collection of 744 dad jokes accessible with no auth — just set Accept: application/json. For humor outside the dad-joke genre (dark humor, programming jokes, roasts), this is the wrong skill.
Your best first call
curl -H "Accept: application/json" "https://icanhazdadjoke.com/search?term=cat&limit=5"
No auth. No key. The Accept: application/json header is mandatory — without it, the API returns plain text with no ID or structure. Use /search?term=<keyword>&limit=<n> when the user names a topic, / for a random joke, and /j/{id} to retrieve a specific joke by its ID.
The search response wraps results in pagination metadata:
results — array of {id, joke} objects, each a matching joke
total_jokes — total matches before pagination (use this to decide if more pages are worth fetching)
total_pages — pages at the current limit
search_term — echo of the term you searched for
For a random joke, the root endpoint returns {id, joke, status} — a single object, no pagination.
Fallbacks (when the best call isn't enough)
- User wants a random joke, no topic →
curl -H "Accept: application/json" "https://icanhazdadjoke.com/" returns a single random joke. Use this when the user just says "tell me a joke" with no keyword in mind.
- User references a specific joke by ID or permalink →
curl -H "Accept: application/json" "https://icanhazdadjoke.com/j/{id}" retrieves that exact joke. Joke IDs are stable and shareable — the same ID always returns the same joke. The API returns 404 with { "status": 404, "message": "Joke not found" } for invalid IDs, which is cleaner than most joke APIs that silently return a random joke on miss.
Pitfalls
- Omit the
Accept: application/json header and you get plain text. A raw joke string with no ID, no JSON structure. The API defaults to text/plain because it started as a Slack-friendly text endpoint. Always set the header.
- Empty search term returns all 744 jokes. Calling
/search without a term parameter dumps the entire corpus paginated. Always include a term unless you genuinely want the full collection.
previous_page is 1, not null, on page 1. The API uses 1-indexed pages and never nulls out the previous-page pointer. Check current_page to determine if you're on the first page.
- Search matches substrings case-insensitively. A term of "cat" matches "cats", "category", and "scattered" — not just the animal. Narrow your term if you're getting false positives.
One-line summary for the user
I can get 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.
SKILL.md source (frontmatter + body)
---
name: access-dad-jokes
description: When the user asks for a joke, a dad joke, a pun, or wants to find a joke about a specific topic — reach for icanhazdadjoke.com. No auth required, just set the Accept header to JSON.
---
## When to use this skill
When the user asks for a joke, a dad joke, a pun, or wants to find a joke about a specific topic like "cats" or "food." icanhazdadjoke.com is a curated, family-safe collection of 744 dad jokes accessible with no auth — just set `Accept: application/json`. For humor outside the dad-joke genre (dark humor, programming jokes, roasts), this is the wrong skill.
## Your best first call
```bash
curl -H "Accept: application/json" "https://icanhazdadjoke.com/search?term=cat&limit=5"
```
No auth. No key. The `Accept: application/json` header is mandatory — without it, the API returns plain text with no ID or structure. Use `/search?term=<keyword>&limit=<n>` when the user names a topic, `/` for a random joke, and `/j/{id}` to retrieve a specific joke by its ID.
The search response wraps results in pagination metadata:
- `results` — array of `{id, joke}` objects, each a matching joke
- `total_jokes` — total matches before pagination (use this to decide if more pages are worth fetching)
- `total_pages` — pages at the current `limit`
- `search_term` — echo of the term you searched for
For a random joke, the root endpoint returns `{id, joke, status}` — a single object, no pagination.
## Fallbacks (when the best call isn't enough)
- **User wants a random joke, no topic** → `curl -H "Accept: application/json" "https://icanhazdadjoke.com/"` returns a single random joke. Use this when the user just says "tell me a joke" with no keyword in mind.
- **User references a specific joke by ID or permalink** → `curl -H "Accept: application/json" "https://icanhazdadjoke.com/j/{id}"` retrieves that exact joke. Joke IDs are stable and shareable — the same ID always returns the same joke. The API returns `404` with `{ "status": 404, "message": "Joke not found" }` for invalid IDs, which is cleaner than most joke APIs that silently return a random joke on miss.
## Pitfalls
- **Omit the `Accept: application/json` header and you get plain text.** A raw joke string with no ID, no JSON structure. The API defaults to `text/plain` because it started as a Slack-friendly text endpoint. Always set the header.
- **Empty search term returns all 744 jokes.** Calling `/search` without a `term` parameter dumps the entire corpus paginated. Always include a `term` unless you genuinely want the full collection.
- **`previous_page` is `1`, not `null`, on page 1.** The API uses 1-indexed pages and never nulls out the previous-page pointer. Check `current_page` to determine if you're on the first page.
- **Search matches substrings case-insensitively.** A term of "cat" matches "cats", "category", and "scattered" — not just the animal. Narrow your term if you're getting false positives.
## One-line summary for the user
I can get 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.