- Images are hosted on Vultr, The Everywhere Cloud
- To add your own images submit a pull request to https://github.com/jigsawpieces/dog-api-images
- Some API requests are cached from AWS lambda https://github.com/ElliottLandsborough/dog-ceo-api-golang
- p5.js: https://editor.p5js.org/codingtrain/sketches/lQxT7PTKC
- Vanilla JS: https://codepen.io/elliottlan/pen/MNEWNx
- Jquery: https://codepen.io/elliottlan/pen/KOXKLG
- Flutter: https://github.com/LIVELUCKY/dogs
- Node.js: https://github.com/mrbrunelli/dog-time-decorator
- php 8.3+
- Symfony 6
- modules
- composer
- run
make build; make install; make test;for unit tests
Not sure that the yaml module is actually require below:
$ composer check-platform-reqs
Checking platform requirements for packages in the vendor dir
composer-plugin-api 2.3.0 success
composer-runtime-api 2.2.2 success
ext-ctype 8.1.12 success
ext-dom 20031129 success
ext-filter 8.1.12 success
ext-iconv 8.1.12 success
ext-json 8.1.12 success
ext-libxml 8.1.12 success
ext-mbstring * success provided by symfony/polyfill-mbstring
ext-phar 8.1.12 success
ext-tokenizer 8.1.12 success
ext-xml 8.1.12 success
ext-xmlwriter 8.1.12 success
ext-yaml 2.2.2 success
php 8.1.12 success- Clone repo
- composer install
- cd public
- php -S 127.0.0.1:6969
DOG_CEO_CACHE_KEY="something-really-secure"
DOG_CEO_LAMBDA_URI=https://example.execute-api.us-east-1.amazonaws.com/dev/
$ curl -X GET http://127.0.0.1:8000/cache-clear -H 'auth-key: something-really-secure'
All endpoints return JSON in this format:
{
"message": "...",
"status": "success"
}The message field contains the actual data and varies by endpoint:
- String: single image URL
- Array: lists of breeds, sub-breeds, or multiple image URLs
- Object: breeds with their sub-breeds (key-value pairs)
Error responses include a code field:
{
"status": "error",
"message": "Breed not found (main breed does not exist)",
"code": 404
}List all breed names including sub breeds.
Returns object with breed names as keys and sub-breed arrays as values. Empty arrays indicate no sub-breeds exist for that breed.
{
"message": {
"affenpinscher": [],
"bulldog": ["boston", "english", "french"],
"hound": ["afghan", "basset", "blood", "english", "ibizan", "plott", "walker"],
// ... 98 breeds total
},
"status": "success"
}Get random breed including any sub breeds.
Get 10 random breeds including any sub breeds.
List all main breed names.
Returns simple array of breed names (excludes sub-breed information).
Get single random main breed.
Get 10 random main breeds.
List sub breeds for a specific breed.
Returns array of sub-breed names without the main breed prefix. Returns empty array if breed has no sub-breeds.
List random sub breed.
List 10 random sub breeds.
Get main breed info (data is incomplete, see content folder).
Note: Most breeds return 404 with message "No info file for this breed exists". This is a known limitation.
Get sub breed info (data is incomplete, see content folder).
Note: Most sub-breeds return 404 with message "No info file for this breed exists". This is a known limitation.
Random image from any breed.
Get 3 random images from any breed (max. 50)
Returns array of image URLs. Important: Requests exceeding 50 images are silently capped at 50 (no error returned). Invalid numbers (non-numeric, zero, negative) default to 1 image.
Get all breed images.
Important: Returns images from the main breed AND all its sub-breeds combined. For example, /breed/hound/images returns 808 images from all hound sub-breeds (afghan, basset, blood, english, ibizan, plott, walker). No pagination is applied.
Get random image from a breed (and all its sub-breeds).
Get 4 random images from a breed (and all its sub-breeds).
Get all images from a sub breed.
Get random image from a sub breed.
Get 5 random images from a sub breed.
Sub-breeds are variations within a main breed. Key behaviors:
/breed/{breed}/list- Returns sub-breed names as array:["afghan", "basset", ...]/breed/{breed}/images- Returns ALL images including all sub-breeds (aggregated)/breed/{breed}/{sub-breed}/images- Returns only that specific sub-breed's images
Sub-breed names in responses do not include the main breed prefix, but image URLs use hyphenated format: hound-afghan.
Example breeds with sub-breeds:
bulldog: boston, english, frenchhound: afghan, basset, blood, english, ibizan, plott, walkerterrier: 25 sub-breeds including american, border, scottish, yorkshire
All image URLs follow this pattern:
https://images.dog.ceo/breeds/{breed-subbreed}/{filename}.jpg
- Direct CDN links (no authentication required)
- All images are .jpg format
- Can be used directly in HTML
<img>tags - Example:
https://images.dog.ceo/breeds/hound-afghan/n02088094_1003.jpg
The API returns different error messages for different scenarios:
Invalid breed name (404):
{
"status": "error",
"message": "Breed not found (main breed does not exist)",
"code": 404
}Invalid sub-breed for valid breed (404):
{
"status": "error",
"message": "Breed not found (no sub breeds exist for this main breed)",
"code": 404
}Missing breed info files (404):
{
"status": "error",
"message": "Breed not found (No info file for this breed exists)",
"code": 404
}Invalid route/typo (404):
{
"status": "error",
"message": "No route found for \"GET http://dog.ceo/api/...\""",
"code": 404
}- Breed names are case-sensitive: Use lowercase only.
houndworks,Houndreturns 404. - Number parameters are permissive: Non-numeric values, zero, and negative numbers all default to 1 image (no error).
- 50 image limit is enforced silently: Requesting 51+ images returns exactly 50 with no error indication.
- No pagination: Endpoints like
/breed/{breed}/imagesreturn all images at once (can be hundreds).
These endpoints might change in the future...
https://dog.ceo/api/breeds/image/random/alt
https://dog.ceo/api/breeds/image/random/1/alt
https://dog.ceo/api/breeds/image/random/9/alt
https://dog.ceo/api/breed/hound/images/alt
https://dog.ceo/api/breed/hound/images/random/1/alt
https://dog.ceo/api/breed/hound/images/random/9/alt
https://dog.ceo/api/breed/hound/afghan/images/alt
https://dog.ceo/api/breed/hound/afghan/images/random/alt
Add 'Content-Type' request header containing 'application/xml' to any endpoint.
