Skip to content

Instantly share code, notes, and snippets.

@0x7466
Created January 27, 2026 10:43
Show Gist options
  • Select an option

  • Save 0x7466/1fdfea3b2c20589296b49397d4253066 to your computer and use it in GitHub Desktop.

Select an option

Save 0x7466/1fdfea3b2c20589296b49397d4253066 to your computer and use it in GitHub Desktop.
Unsplash OpenAPI Spec
openapi: 3.1.1
info:
title: Unsplash API (Unofficial OpenAPI)
version: "1.0.0"
description: >
OpenAPI 3.1 specification for the Unsplash JSON API (v1). This spec covers the major
public endpoints (photos, users, collections, search, current user) and models
based on the provided Unsplash documentation.
Note: auth options include Client-ID (header or query) and user Bearer tokens.
servers:
- url: https://api.unsplash.com
description: Unsplash API base URL (v1)
tags:
- name: Photos
description: Photo listing, details, random, download tracking, and updates
- name: Users
description: Public user profiles, current user endpoints
- name: Collections
description: Collections CRUD and managing photos in collections
- name: Search
description: Search photos, collections, users
- name: Topics
description: Topic listing and photos by topic
- name: Stats
description: Statistics endpoints
paths:
/photos:
get:
tags: [Photos]
summary: List photos (editorial feed)
operationId: listPhotos
parameters:
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/per_page'
description: Returns an abbreviated list of photo objects. For full photo use GET /photos/{id}.
responses:
'200':
description: A paginated list of photo summary objects
headers:
X-Per-Page:
description: Number of items returned per page
schema:
type: integer
X-Total:
description: Total number of elements
schema:
type: integer
Link:
description: Pagination links
schema:
type: string
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/PhotoSummary'
examples:
sample:
value:
- id: "LBI7cgq3pbM"
created_at: "2016-05-03T11:00:28-04:00"
width: 5245
height: 3497
color: "#60544D"
blur_hash: "LoC%a7IoIVxZ_NM|M{s:%hRjWAo0"
description: "A man drinking a coffee."
urls:
raw: "https://images.unsplash.com/face-springmorning.jpg"
full: "https://images.unsplash.com/face-springmorning.jpg?q=75&fm=jpg"
regular: "https://images.unsplash.com/face-springmorning.jpg?q=75&fm=jpg&w=1080&fit=max"
small: "https://images.unsplash.com/face-springmorning.jpg?q=75&fm=jpg&w=400&fit=max"
thumb: "https://images.unsplash.com/face-springmorning.jpg?q=75&fm=jpg&w=200&fit=max"
'4XX':
$ref: '#/components/responses/Error4xx'
'5XX':
$ref: '#/components/responses/Error5xx'
/photos/{id}:
get:
tags: [Photos]
summary: Get a photo
operationId: getPhotoById
parameters:
- name: id
in: path
required: true
description: Photo ID
schema:
type: string
responses:
'200':
description: Full photo object
content:
application/json:
schema:
$ref: '#/components/schemas/Photo'
examples:
sample:
value:
id: "Dwu85P9SOIk"
created_at: "2016-05-03T11:00:28-04:00"
updated_at: "2016-07-10T11:00:01-05:00"
width: 2448
height: 3264
color: "#6E633A"
blur_hash: "LFC$yHwc8^$yIAS$%M%00KxukYIp"
downloads: 1345
description: "A man drinking a coffee."
exif:
make: "Canon"
model: "Canon EOS 40D"
exposure_time: "0.011111111111111112"
aperture: "4.970854"
focal_length: "37"
iso: 100
location:
city: "Montreal"
country: "Canada"
position:
latitude: 45.473298
longitude: -73.638488
urls:
raw: "https://images.unsplash.com/photo-1417325384643-aac51acc9e5d"
full: "https://images.unsplash.com/photo-1417325384643-aac51acc9e5d?q=75&fm=jpg"
regular: "https://images.unsplash.com/photo-1417325384643-aac51acc9e5d?q=75&fm=jpg&w=1080&fit=max"
small: "https://images.unsplash.com/photo-1417325384643-aac51acc9e5d?q=75&fm=jpg&w=400&fit=max"
thumb: "https://images.unsplash.com/photo-1417325384643-aac51acc9e5d?q=75&fm=jpg&w=200&fit=max"
'404':
description: Photo not found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'4XX':
$ref: '#/components/responses/Error4xx'
'5XX':
$ref: '#/components/responses/Error5xx'
/photos/random:
get:
tags: [Photos]
summary: Get a random photo
operationId: getRandomPhoto
parameters:
- name: collections
in: query
schema:
type: string
description: Comma-separated collection IDs to filter selection
- name: topics
in: query
schema:
type: string
description: Comma-separated topic IDs
- name: username
in: query
schema:
type: string
description: Limit selection to a single user
- name: query
in: query
schema:
type: string
description: Search term
- name: orientation
in: query
schema:
type: string
enum: [landscape, portrait, squarish]
- name: content_filter
in: query
schema:
type: string
enum: [low, high]
description: "Content safety filter (default: low)"
- name: count
in: query
schema:
type: integer
minimum: 1
maximum: 30
description: Number of photos to return (default 1; when present response is an array)
responses:
'200':
description: Random photo or array of photos
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/Photo'
- type: array
items:
$ref: '#/components/schemas/Photo'
examples:
single:
value:
id: "Dwu85P9SOIk"
description: "A man drinking a coffee."
multiple:
value:
- id: "Dwu85P9SOIk"
description: "A man drinking a coffee."
- id: "eOLpJytrbsQ"
description: "Another example"
'4XX':
$ref: '#/components/responses/Error4xx'
'5XX':
$ref: '#/components/responses/Error5xx'
/photos/{id}/download:
get:
tags: [Photos]
summary: Track a photo download
operationId: trackPhotoDownload
parameters:
- name: id
in: path
required: true
description: Photo ID to track download for
schema:
type: string
responses:
'200':
description: Returns a tracking URL (caller should follow if necessary)
content:
application/json:
schema:
type: object
properties:
url:
type: string
format: uri
required: [url]
examples:
sample:
value:
url: "https://image.unsplash.com/example"
'4XX':
$ref: '#/components/responses/Error4xx'
'5XX':
$ref: '#/components/responses/Error5xx'
/me:
get:
tags: [Users]
summary: Get current authenticated user's profile
operationId: getCurrentUser
security:
- bearerAuth: []
responses:
'200':
description: Current user profile
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'401':
$ref: '#/components/responses/Unauthorized'
'4XX':
$ref: '#/components/responses/Error4xx'
put:
tags: [Users]
summary: Update the current user's profile
operationId: updateCurrentUser
security:
- bearerAuth: []
requestBody:
description: Fields to update on the user profile (all optional)
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UserUpdate'
examples:
update:
value:
username: "jimmyexample"
first_name: "James"
bio: "Updated bio"
responses:
'200':
description: Updated user profile
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'403':
description: Missing write_user scope or forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'4XX':
$ref: '#/components/responses/Error4xx'
/users/{username}:
get:
tags: [Users]
summary: Get a user's public profile
operationId: getUserByUsername
parameters:
- name: username
in: path
required: true
description: Username
schema:
type: string
responses:
'200':
description: Public user profile
content:
application/json:
schema:
$ref: '#/components/schemas/UserPublic'
'404':
description: User not found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'4XX':
$ref: '#/components/responses/Error4xx'
/users/{username}/photos:
get:
tags: [Users]
summary: List a user's photos
operationId: listUserPhotos
parameters:
- name: username
in: path
required: true
schema:
type: string
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/per_page'
- name: order_by
in: query
schema:
type: string
enum: [latest, oldest, popular, views, downloads]
description: Sort order
- name: orientation
in: query
schema:
type: string
enum: [landscape, portrait, squarish]
responses:
'200':
description: Array of photo summary objects
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/PhotoSummary'
'4XX':
$ref: '#/components/responses/Error4xx'
/search/photos:
get:
tags: [Search]
summary: Search photos
operationId: searchPhotos
parameters:
- name: query
in: query
required: true
schema:
type: string
description: Search terms
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/per_page'
- name: order_by
in: query
schema:
type: string
enum: [latest, relevant]
description: "Sort results (default: relevant)"
- name: collections
in: query
schema:
type: string
description: Comma-separated collection IDs to narrow search
- name: color
in: query
schema:
type: string
enum: [black_and_white, black, white, yellow, orange, red, purple, magenta, green, teal, blue]
- name: orientation
in: query
schema:
type: string
enum: [landscape, portrait, squarish]
responses:
'200':
description: Search results with pagination metadata
content:
application/json:
schema:
$ref: '#/components/schemas/SearchPhotosResponse'
examples:
sample:
value:
total: 133
total_pages: 7
results:
- id: "eOLpJytrbsQ"
created_at: "2014-11-18T14:35:36-05:00"
width: 4000
height: 3000
color: "#A7A2A1"
blur_hash: "LaLXMa9Fx[D%~q%MtQM|kDRjtRIU"
description: "A man drinking a coffee."
urls:
raw: "https://images.unsplash.com/photo-1416339306562-f3d12fefd36f"
full: "https://hd.unsplash.com/photo-1416339306562-f3d12fefd36f"
regular: "https://images.unsplash.com/photo-1416339306562-f3d12fefd36f?ixlib=rb-0.3.5&q=80&fm=jpg&w=1080&fit=max"
'4XX':
$ref: '#/components/responses/Error4xx'
/collections:
get:
tags: [Collections]
summary: List collections
operationId: listCollections
parameters:
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/per_page'
responses:
'200':
description: Array of collection summaries
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Collection'
'4XX':
$ref: '#/components/responses/Error4xx'
post:
tags: [Collections]
summary: Create a new collection
operationId: createCollection
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
title:
type: string
description:
type: string
private:
type: boolean
required: [title]
examples:
create:
value:
title: "Makers: Cat and Ben"
description: "Behind-the-scenes photos"
private: false
responses:
'201':
description: Created collection
content:
application/json:
schema:
$ref: '#/components/schemas/Collection'
'403':
description: Missing write_collections scope or forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/collections/{id}:
get:
tags: [Collections]
summary: Get a collection
operationId: getCollectionById
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Collection object
content:
application/json:
schema:
$ref: '#/components/schemas/Collection'
'404':
description: Collection not found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
put:
tags: [Collections]
summary: Update a collection
operationId: updateCollection
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
title:
type: string
description:
type: string
private:
type: boolean
examples:
update:
value:
title: "Updated title"
responses:
'200':
description: Updated collection
content:
application/json:
schema:
$ref: '#/components/schemas/Collection'
'403':
description: Forbidden (missing scope)
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
delete:
tags: [Collections]
summary: Delete a collection
operationId: deleteCollection
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'204':
description: No Content (collection deleted)
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/collections/{collection_id}/add:
post:
tags: [Collections]
summary: Add a photo to a collection
operationId: addPhotoToCollection
security:
- bearerAuth: []
parameters:
- name: collection_id
in: path
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
photo_id:
type: string
required: [photo_id]
examples:
add:
value:
photo_id: "cnwIyn_BTkc"
responses:
'201':
description: Photo added to collection
content:
application/json:
schema:
type: object
properties:
photo:
$ref: '#/components/schemas/PhotoSummary'
collection:
$ref: '#/components/schemas/Collection'
user:
$ref: '#/components/schemas/User'
'4XX':
$ref: '#/components/responses/Error4xx'
components:
parameters:
page:
name: page
in: query
description: "Page number to retrieve (default: 1)"
schema:
type: integer
default: 1
per_page:
name: per_page
in: query
description: "Number of items per page (default: 10; max: 30)"
schema:
type: integer
default: 10
maximum: 30
AuthorizationHeader:
name: Authorization
in: header
required: false
description: "Pass Client-ID or Bearer token. Examples: 'Client-ID YOUR_ACCESS_KEY' or 'Bearer USER_ACCESS_TOKEN'"
schema:
type: string
securitySchemes:
clientIdHeader:
type: apiKey
in: header
name: Authorization
description: "Public authentication using 'Authorization: Client-ID YOUR_ACCESS_KEY' header."
clientIdQuery:
type: apiKey
in: query
name: client_id
description: "Public authentication using client_id query parameter: ?client_id=YOUR_ACCESS_KEY"
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: "User authentication (Bearer token) obtained via Unsplash user auth workflow."
schemas:
ErrorResponse:
type: object
properties:
errors:
type: array
items:
type: string
example:
errors:
- "Username is missing"
- "Password cannot be blank"
PhotoURLs:
type: object
properties:
raw:
type: string
format: uri
full:
type: string
format: uri
regular:
type: string
format: uri
small:
type: string
format: uri
thumb:
type: string
format: uri
required: [raw, full, regular, small, thumb]
Exif:
type: object
properties:
make:
type: string
model:
type: string
name:
type: string
exposure_time:
type: string
aperture:
type: string
focal_length:
type: string
iso:
type: integer
Location:
type: object
properties:
name:
type: string
city:
type: string
country:
type: string
position:
type: object
properties:
latitude:
type: number
format: double
longitude:
type: number
format: double
UserLinks:
type: object
properties:
self:
type: string
format: uri
html:
type: string
format: uri
photos:
type: string
format: uri
portfolio:
type: string
format: uri
UserProfileImage:
type: object
properties:
small:
type: string
format: uri
medium:
type: string
format: uri
large:
type: string
format: uri
User:
type: object
properties:
id:
type: string
updated_at:
type: string
format: date-time
username:
type: string
first_name:
type: string
last_name:
type: string
name:
type: string
twitter_username:
type: string
instagram_username:
type: string
portfolio_url:
type: string
format: uri
bio:
type: string
location:
type: string
total_collections:
type: integer
downloads:
type: integer
uploads_remaining:
type: integer
links:
$ref: '#/components/schemas/UserLinks'
profile_image:
$ref: '#/components/schemas/UserProfileImage'
email:
type: string
format: email
example:
id: "pXhwzz1JtQU"
updated_at: "2016-07-10T11:00:01-05:00"
username: "jimmyexample"
first_name: "James"
last_name: "Example"
email: "[email protected]"
bio: "The user's bio"
links:
self: "https://api.unsplash.com/users/jimmyexample"
html: "https://unsplash.com/jimmyexample"
photos: "https://api.unsplash.com/users/jimmyexample/photos"
UserPublic:
type: object
properties:
id:
type: string
username:
type: string
name:
type: string
first_name:
type: string
last_name:
type: string
instagram_username:
type: string
twitter_username:
type: string
portfolio_url:
type: string
format: uri
total_collections:
type: integer
profile_image:
$ref: '#/components/schemas/UserProfileImage'
links:
$ref: '#/components/schemas/UserLinks'
UserUpdate:
type: object
properties:
username:
type: string
first_name:
type: string
last_name:
type: string
email:
type: string
format: email
url:
type: string
format: uri
location:
type: string
bio:
type: string
instagram_username:
type: string
additionalProperties: false
PhotoSummary:
type: object
properties:
id:
type: string
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
width:
type: integer
height:
type: integer
color:
type: string
blur_hash:
type: string
description:
type: string
user:
$ref: '#/components/schemas/UserPublic'
current_user_collections:
type: array
items:
type: object
urls:
$ref: '#/components/schemas/PhotoURLs'
links:
type: object
example:
id: "LBI7cgq3pbM"
created_at: "2016-05-03T11:00:28-04:00"
width: 5245
height: 3497
color: "#60544D"
blur_hash: "LoC%a7IoIVxZ_NM|M{s:%hRjWAo0"
description: "A man drinking a coffee."
urls:
raw: "https://images.unsplash.com/face-springmorning.jpg"
full: "https://images.unsplash.com/face-springmorning.jpg?q=75&fm=jpg"
regular: "https://images.unsplash.com/face-springmorning.jpg?q=75&fm=jpg&w=1080&fit=max"
Photo:
allOf:
- $ref: '#/components/schemas/PhotoSummary'
- type: object
properties:
downloads:
type: integer
public_domain:
type: boolean
exif:
$ref: '#/components/schemas/Exif'
location:
$ref: '#/components/schemas/Location'
tags:
type: array
items:
type: object
properties:
title:
type: string
Collection:
type: object
properties:
id:
type: integer
title:
type: string
description:
type: string
published_at:
type: string
format: date-time
last_collected_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
featured:
type: boolean
total_photos:
type: integer
private:
type: boolean
share_key:
type: string
cover_photo:
oneOf:
- $ref: '#/components/schemas/PhotoSummary'
- type: "null"
user:
$ref: '#/components/schemas/UserPublic'
links:
type: object
example:
id: 296
title: "I like a man with a beard."
description: "Yeah even Santa..."
published_at: "2016-01-27T18:47:13-05:00"
total_photos: 12
private: false
links:
self: "https://api.unsplash.com/collections/296"
html: "https://unsplash.com/collections/296"
photos: "https://api.unsplash.com/collections/296/photos"
SearchPhotosResponse:
type: object
properties:
total:
type: integer
total_pages:
type: integer
results:
type: array
items:
$ref: '#/components/schemas/PhotoSummary'
example:
total: 133
total_pages: 7
results:
- id: "eOLpJytrbsQ"
description: "A man drinking a coffee."
responses:
Error4xx:
description: Client error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
Error5xx:
description: Server error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
Unauthorized:
description: Unauthorized - invalid or missing authentication
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
examples:
PhotoSummaryExample:
summary: Photo summary example
value:
id: "LBI7cgq3pbM"
description: "A man drinking a coffee."
security: [] # No global security enforced; operations declare security where required
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment