@lap v0.3
# Machine-readable API spec. Each @endpoint block is one API call.
@api Shutterstock API Explorer
@base https://api.shutterstock.com
@version 1.2.0
@auth Bearer basic | OAuth2
@endpoints 109
@hint download_for_search
@toc images(20), bulk_search(1), videos(18), audio(17), sfx(6), editorial(24), cv(4), catalog(7), contributors(5), user(3), test(2), oauth(2)

@group images
@endpoint GET /v2/images/search
@desc Search for images
@optional {library: [str]=shutterstock # Search within different Shutterstock owned libraries, added_date: str(date) # Show images added on the specified date, added_date_start: str(date) # Show images added on or after the specified date, aspect_ratio_min: num # Show images with the specified aspect ratio or higher, using a positive decimal of the width divided by the height, such as 1.7778 for a 16:9 image, aspect_ratio_max: num # Show images with the specified aspect ratio or lower, using a positive decimal of the width divided by the height, such as 1.7778 for a 16:9 image, aspect_ratio: num # Show images with the specified aspect ratio, using a positive decimal of the width divided by the height, such as 1.7778 for a 16:9 image, added_date_end: str(date) # Show images added before the specified date, category: str # Show images with the specified Shutterstock-defined category; specify a category name or ID, color: str # Specify either a hexadecimal color in the format '4F21EA' or 'grayscale'; the API returns images that use similar colors, contributor: [str] # Show images with the specified contributor names or IDs, allows multiple, contributor_country: any # Show images from contributors in one or more specified countries, or start with NOT to exclude a country from the search, fields: str # Fields to display in the response; see the documentation for the fields parameter in the overview section, height: int # (Deprecated; use height_from and height_to instead) Show images with the specified height, height_from: int # Show images with the specified height or larger, in pixels, height_to: int # Show images with the specified height or smaller, in pixels, image_type: [str] # Show images of the specified type, keyword_safe_search: bool=true # Hide results with potentially unsafe keywords, language: str(ar/bg/bn/cs/da/de/el/en/es/fi/fr/gu/he/hi/hr/hu/id/it/ja/kn/ko/ml/mr/nb/nl/or/pl/pt/ro/ru/sk/sl/sv/ta/te/th/tr/uk/ur/vi/zh/zh-Hant) # Set query and result language (uses Accept-Language header if not set), license: [str] # Show only images with the specified license, model: [str] # Show image results with the specified model IDs, orientation: str(horizontal/vertical) # Show image results with horizontal or vertical orientation, page: int=1 # Page number, per_page: int=20 # Number of results per page, people_model_released: bool # Show images of people with a signed model release, people_age: str(infants/children/teenagers/20s/30s/40s/50s/60s/older) # Show images that feature people of the specified age category, people_ethnicity: [str] # Show images with people of the specified ethnicities, or start with NOT to show images without those ethnicities, people_gender: str(male/female/both) # Show images with people of the specified gender, people_number: int # Show images with the specified number of people, query: str # One or more search terms separated by spaces; you can use NOT to filter out images that match a term, region: any # Raise or lower search result rankings based on the result's relevance to a specified region; you can provide a country code or an IP address from which the API infers a country, safe: bool=true # Enable or disable safe search, sort: str(newest/popular/relevance/random)=popular # Sort by, spellcheck_query: bool=true # Spellcheck the search query and return results on suggested spellings, view: str(minimal/full)=minimal # Amount of detail to render in the response, width: int # (Deprecated; use width_from and width_to instead) Show images with the specified width, width_from: int # Show images with the specified width or larger, in pixels, width_to: int # Show images with the specified width or smaller, in pixels}
@returns(200) {data: [map], message: str, page: int, per_page: int, search_id: str, spellcheck_info: map, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endgroup

@group bulk_search
@endpoint POST /v2/bulk_search/images
@desc Run multiple image searches
@optional {added_date: str(date) # Show images added on the specified date, added_date_start: str(date) # Show images added on or after the specified date, aspect_ratio_min: num # Show images with the specified aspect ratio or higher, using a positive decimal of the width divided by the height, such as 1.7778 for a 16:9 image, aspect_ratio_max: num # Show images with the specified aspect ratio or lower, using a positive decimal of the width divided by the height, such as 1.7778 for a 16:9 image, aspect_ratio: num # Show images with the specified aspect ratio, using a positive decimal of the width divided by the height, such as 1.7778 for a 16:9 image, added_date_end: str(date) # Show images added before the specified date, category: str # Show images with the specified Shutterstock-defined category; specify a category name or ID, color: str # Specify either a hexadecimal color in the format '4F21EA' or 'grayscale'; the API returns images that use similar colors, contributor: [str] # Show images with the specified contributor names or IDs, allows multiple, contributor_country: any # Show images from contributors in one or more specified countries, or start with NOT to exclude a country from the search, fields: str # Fields to display in the response; see the documentation for the fields parameter in the overview section, height: int # (Deprecated; use height_from and height_to instead) Show images with the specified height, height_from: int # Show images with the specified height or larger, in pixels, height_to: int # Show images with the specified height or smaller, in pixels, image_type: [str] # Show images of the specified type, keyword_safe_search: bool=true # Hide results with potentially unsafe keywords, language: str(ar/bg/bn/cs/da/de/el/en/es/fi/fr/gu/he/hi/hr/hu/id/it/ja/kn/ko/ml/mr/nb/nl/or/pl/pt/ro/ru/sk/sl/sv/ta/te/th/tr/uk/ur/vi/zh/zh-Hant) # Set query and result language (uses Accept-Language header if not set), license: [str] # Show only images with the specified license, model: [str] # Show image results with the specified model IDs, orientation: str(horizontal/vertical) # Show image results with horizontal or vertical orientation, page: int=1 # Page number, per_page: int=20 # Number of results per page, people_model_released: bool # Show images of people with a signed model release, people_age: str(infants/children/teenagers/20s/30s/40s/50s/60s/older) # Show images that feature people of the specified age category, people_ethnicity: [str] # Show images with people of the specified ethnicities, or start with NOT to show images without those ethnicities, people_gender: str(male/female/both) # Show images with people of the specified gender, people_number: int # Show images with the specified number of people, region: any # Raise or lower search result rankings based on the result's relevance to a specified region; you can provide a country code or an IP address from which the API infers a country, safe: bool=true # Enable or disable safe search, sort: str(newest/popular/relevance/random)=popular # Sort by, spellcheck_query: bool=true # Spellcheck the search query and return results on suggested spellings, view: str(minimal/full)=minimal # Amount of detail to render in the response, width: int # (Deprecated; use width_from and width_to instead) Show images with the specified width, width_from: int # Show images with the specified width or larger, in pixels, width_to: int # Show images with the specified width or smaller, in pixels}
@returns(200) {results: [map], bulk_search_id: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}
@example_request [{"query":"cat","license":["editorial"],"sort":"popular"},{"query":"dog","orientation":"horizontal"}]

@endgroup

@group images
@endpoint GET /v2/images/search/suggestions
@desc Get suggestions for a search term
@required {query: str # Search term for which you want keyword suggestions}
@optional {limit: int=10 # Limit the number of suggestions}
@returns(200) {data: [str]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint POST /v2/images/search/suggestions
@desc Get keywords from text
@required {text: str # Plain text to extract keywords from}
@returns(200) {keywords: [str]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}
@example_request {"text":"Planting flowers is a great way to make springtime more beautiful."}

@endpoint GET /v2/images
@desc List images
@required {id: [str(asset-id)] # One or more image IDs}
@optional {view: str(minimal/full)=minimal # Amount of detail to render in the response, search_id: str # The ID of the search that is related to this request}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/images/{id}
@desc Get details about images
@required {id: str(asset-id) # Image ID}
@optional {language: str(ar/bg/bn/cs/da/de/el/en/es/fi/fr/gu/he/hi/hr/hu/id/it/ja/kn/ko/ml/mr/nb/nl/or/pl/pt/ro/ru/sk/sl/sv/ta/te/th/tr/uk/ur/vi/zh/zh-Hant) # Language for the keywords and categories in the response, view: str(minimal/full)=full # Amount of detail to render in the response, search_id: str # The ID of the search that is related to this request}
@returns(200) {added_date: str(date), affiliate_url: str(uri), aspect: num, assets: map{huge_jpg: map{display_name: str, dpi: int, file_size: int, format: str, height: int, is_licensable: bool, width: int}, huge_thumb: map{height: int, url: str, width: int}, large_thumb: map{height: int, url: str, width: int}, medium_jpg: map{display_name: str, dpi: int, file_size: int, format: str, height: int, is_licensable: bool, width: int}, preview: map{height: int, url: str, width: int}, preview_1000: map{height: int, url: str, width: int}, preview_1500: map{height: int, url: str, width: int}, small_jpg: map{display_name: str, dpi: int, file_size: int, format: str, height: int, is_licensable: bool, width: int}, small_thumb: map{height: int, url: str, width: int}, supersize_jpg: map{display_name: str, dpi: int, file_size: int, format: str, height: int, is_licensable: bool, width: int}, vector_eps: map{display_name: str, dpi: int, file_size: int, format: str, height: int, is_licensable: bool, width: int}, mosaic: map{height: int, url: str, width: int}}, categories: [map], contributor: map{id: str}, description: str, has_model_release: bool, has_property_release: bool, id: str, image_type: str, is_adult: bool, is_editorial: bool, is_illustration: bool, keywords: [str], media_type: str, model_releases: [map], models: [map], releases: [str], url: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/images/categories
@desc List image categories
@optional {language: str(ar/bg/bn/cs/da/de/el/en/es/fi/fr/gu/he/hi/hr/hu/id/it/ja/kn/ko/ml/mr/nb/nl/or/pl/pt/ro/ru/sk/sl/sv/ta/te/th/tr/uk/ur/vi/zh/zh-Hant) # Language for the keywords and categories in the response}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/images/{id}/similar
@desc List similar images
@required {id: str # Image ID}
@optional {language: str(ar/bg/bn/cs/da/de/el/en/es/fi/fr/gu/he/hi/hr/hu/id/it/ja/kn/ko/ml/mr/nb/nl/or/pl/pt/ro/ru/sk/sl/sv/ta/te/th/tr/uk/ur/vi/zh/zh-Hant) # Language for the keywords and categories in the response, page: int=1 # Page number, per_page: int=20 # Number of results per page, view: str(minimal/full)=minimal # Amount of detail to render in the response}
@returns(200) {data: [map], message: str, page: int, per_page: int, search_id: str, spellcheck_info: map, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint POST /v2/images/licenses
@desc License images
@required {images: [any] # Images to create licenses for}
@optional {subscription_id: str # Subscription ID to use to license the image, format: str(eps/jpg) # (Deprecated) Image format, size: str(small/medium/huge/vector/custom)=huge # Image size, search_id: str # Search ID that was provided in the results of an image search}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}
@example_request {"images":[{"editorial_acknowledgement":true,"format":"jpg","image_id":"123456789","metadata":{"customer_id":"12345","geo_location":"US","number_viewed":"15","search_term":"dog"},"price":12.34,"show_modal":true,"size":"small","subscription_id":"s12345678"}]}

@endpoint GET /v2/images/licenses
@desc List image licenses
@optional {image_id: str # Show licenses for the specified image ID, license: str # Show images that are available with the specified license, such as `standard` or `enhanced`, page: int=1 # Page number, per_page: int=20 # Number of results per page, sort: str(newest/oldest)=newest # Sort order, username: str # Filter licenses by username of licensee, start_date: str(date-time) # Show licenses created on or after the specified date, end_date: str(date-time) # Show licenses created before the specified date, download_availability: str(all/downloadable/non_downloadable)=all # Filter licenses by download availability, team_history: bool=false # Set to true to see license history for all members of your team.}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint POST /v2/images/licenses/{id}/downloads
@desc Download images
@required {id: str # License ID}
@optional {auth_cookie: map{name!: str, value!: str} # (Deprecated), show_modal: bool # (Deprecated), size: str(small/medium/huge/supersize/vector) # Size of the image, verification_code: str # (Deprecated)}
@returns(200) {url: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}
@example_request {"size":"small"}

@endpoint GET /v2/images/recommendations
@desc List recommended images
@required {id: [str] # Image IDs}
@optional {max_items: int=20 # Maximum number of results returned in the response, safe: bool=true # Restrict results to safe images}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint POST /v2/images/collections
@desc Create image collections
@required {name: str # The name of the collection}
@returns(201) {id: str} # Successfully created image collection
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}
@example_request {"name":"Test Collection 19cf"}

@endpoint GET /v2/images/collections
@desc List image collections
@optional {embed: [str] # Which sharing information to include in the response, such as a URL to the collection, page: int=1 # Page number, per_page: int=100 # Number of results per page}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/images/collections/{id}
@desc Get the details of image collections
@required {id: str # Collection ID}
@optional {embed: [str] # Which sharing information to include in the response, such as a URL to the collection, share_code: str # Code to retrieve a shared collection}
@returns(200) {cover_item: map{added_time: str(date-time), id: str, media_type: str}, created_time: str(date-time), id: str, items_updated_time: str(date-time), name: str, share_code: str, share_url: str, total_item_count: int, updated_time: str(date-time)} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Collection not found}

@endpoint POST /v2/images/collections/{id}
@desc Rename image collections
@required {id: str # Collection ID, name: str # The new name of the collection}
@returns(204) Successfully updated collection
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Collection not found}
@example_request {"name":"My collection with a new name"}

@endpoint DELETE /v2/images/collections/{id}
@desc Delete image collections
@required {id: str # Collection ID}
@returns(204) Successfully deleted collection
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Collection not found}

@endpoint POST /v2/images/collections/{id}/items
@desc Add images to collections
@required {id: str # Collection ID, items: [map{added_time: str(date-time), id!: str, media_type: str}] # List of items}
@returns(204) Successfully added collection items
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Collection not found}
@example_request {"items":[{"id":"49572945"}]}

@endpoint GET /v2/images/collections/{id}/items
@desc Get the contents of image collections
@required {id: str # Collection ID}
@optional {page: int=1 # Page number, per_page: int=100 # Number of results per page, share_code: str # Code to retrieve the contents of a shared collection, sort: str(newest/oldest)=oldest # Sort order}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Collection not found}

@endpoint DELETE /v2/images/collections/{id}/items
@desc Remove images from collections
@required {id: str # Collection ID}
@optional {item_id: [str] # One or more image IDs to remove from the collection}
@returns(204) Successfully removed collection items
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Collection not found}

@endpoint GET /v2/images/updated
@desc List updated images
@optional {type: [str] # Show images that were added, deleted, or edited; by default, the endpoint returns images that were updated in any of these ways, start_date: str(date-or-date-time) # Show images updated on or after the specified date. The API will default to UTC (00:00:00) if no specific time is provided, ensuring consistency., end_date: str(date-or-date-time) # Show images updated before the specified date. The API will default to UTC (00:00:00) if no specific time is provided, ensuring consistency. Please note that the end date must be at least 5 minutes after the start date., interval: str=1 HOUR # Show images updated in the specified time period, where the time period is an interval (like SQL INTERVAL) such as 1 DAY, 6 HOUR, or 30 MINUTE; the default is 1 HOUR, which shows images that were updated in the hour preceding the request, page: int=1 # Page number, per_page: int=100 # Number of results per page, sort: str(newest/oldest)=newest # Sort order}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK

@endgroup

@group videos
@endpoint GET /v2/videos/search
@desc Search for videos
@optional {added_date: str(date) # Show videos added on the specified date, added_date_start: str(date) # Show videos added on or after the specified date, added_date_end: str(date) # Show videos added before the specified date, aspect_ratio: str(4_3/16_9/nonstandard) # Show videos with the specified aspect ratio, category: str # Show videos with the specified Shutterstock-defined category; specify a category name or ID, contributor: [str] # Show videos with the specified artist names or IDs, contributor_country: [str(country-code-2)] # Show videos from contributors in one or more specified countries, duration: int # (Deprecated; use duration_from and duration_to instead) Show videos with the specified duration in seconds, duration_from: int # Show videos with the specified duration or longer in seconds, duration_to: int # Show videos with the specified duration or shorter in seconds, fps: num # (Deprecated; use fps_from and fps_to instead) Show videos with the specified frames per second, fps_from: num # Show videos with the specified frames per second or more, fps_to: num # Show videos with the specified frames per second or fewer, keyword_safe_search: bool=true # Hide results with potentially unsafe keywords, language: str(ar/bg/bn/cs/da/de/el/en/es/fi/fr/gu/he/hi/hr/hu/id/it/ja/kn/ko/ml/mr/nb/nl/or/pl/pt/ro/ru/sk/sl/sv/ta/te/th/tr/uk/ur/vi/zh/zh-Hant) # Set query and result language (uses Accept-Language header if not set), license: [str] # Show only videos with the specified license or licenses, model: [str] # Show videos with each of the specified models, orientation: str(vertical/horizontal) # Search for videos in a specific orientation, page: int=1 # Page number, per_page: int=20 # Number of results per page, people_age: str(infants/children/teenagers/20s/30s/40s/50s/60s/older) # Show videos that feature people of the specified age range, people_ethnicity: [str] # Show videos with people of the specified ethnicities, people_gender: str(male/female/both) # Show videos with people with the specified gender, people_number: int # Show videos with the specified number of people, people_model_released: bool # Show only videos of people with a signed model release, query: str # One or more search terms separated by spaces; you can use NOT to filter out videos that match a term, resolution: str(4k/standard_definition/high_definition) # Show videos with the specified resolution, safe: bool=true # Enable or disable safe search, sort: str(newest/popular/relevance/random)=popular # Sort by one of these categories, view: str(minimal/full)=minimal # Amount of detail to render in the response}
@returns(200) {data: [map], message: str, page: int, per_page: int, total_count: int, search_id: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not found}

@endpoint GET /v2/videos/search/suggestions
@desc Get suggestions for a search term
@required {query: str # Search term for which you want keyword suggestions}
@optional {limit: int=10 # Limit the number of the suggestions}
@returns(200) {data: [str]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/videos
@desc List videos
@required {id: [str(asset-id)] # One or more video IDs}
@optional {view: str(minimal/full)=minimal # Amount of detail to render in the response, search_id: str # The ID of the search that is related to this request}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/videos/{id}
@desc Get details about videos
@required {id: str(asset-id) # Video ID}
@optional {language: str(ar/bg/bn/cs/da/de/el/en/es/fi/fr/gu/he/hi/hr/hu/id/it/ja/kn/ko/ml/mr/nb/nl/or/pl/pt/ro/ru/sk/sl/sv/ta/te/th/tr/uk/ur/vi/zh/zh-Hant) # Language for the keywords and categories in the response, view: str(minimal/full)=full # Amount of detail to render in the response, search_id: str # The ID of the search that is related to this request}
@returns(200) {added_date: str(date), affiliate_url: str(uri), aspect: num, aspect_ratio: str, assets: map{4k: map{display_name: str, file_size: int, format: str, fps: num, height: int, is_licensable: bool, width: int}, hd: map{display_name: str, file_size: int, format: str, fps: num, height: int, is_licensable: bool, width: int}, preview_jpg: map{url: str}, preview_mp4: map{url: str}, preview_webm: map{url: str}, sd: map{display_name: str, file_size: int, format: str, fps: num, height: int, is_licensable: bool, width: int}, thumb_jpg: map{url: str}, thumb_jpgs: map{urls: [str]}, thumb_mp4: map{url: str}, thumb_webm: map{url: str}, web: map{display_name: str, file_size: int, format: str, fps: num, height: int, is_licensable: bool, width: int}}, categories: [map], contributor: map{id: str}, description: str, duration: num, has_model_release: bool, has_property_release: bool, id: str, is_adult: bool, is_editorial: bool, is_select: bool, keywords: [str], media_type: str, models: [map], releases: [map], url: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not found}

@endpoint POST /v2/videos/licenses
@desc License videos
@required {videos: [map{auth_cookie: map, editorial_acknowledgement: bool, metadata: map, price: num, search_id: str, show_modal: bool, size: str, subscription_id: str, video_id!: str}] # Videos to license}
@optional {subscription_id: str # The subscription ID to use for licensing, size: str(web/sd/hd/4k)=web # The size of the video to license, search_id: str # The Search ID that led to this licensing event}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}
@example_request {"videos":[{"size":"hd","subscription_id":"s12345678","video_id":"2140697"}]}

@endpoint GET /v2/videos/licenses
@desc List video licenses
@optional {video_id: str # Show licenses for the specified video ID, license: str # Show videos that are available with the specified license, such as `standard` or `enhanced`, page: int=1 # Page number, per_page: int=20 # Number of results per page, sort: str(newest/oldest)=newest # Sort by oldest or newest videos first, username: str # Filter licenses by username of licensee, start_date: str(date-time) # Show licenses created on or after the specified date, end_date: str(date-time) # Show licenses created before the specified date, download_availability: str(all/downloadable/non_downloadable)=all # Filter licenses by download availability, team_history: bool=false # Set to true to see license history for all members of your team.}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint POST /v2/videos/licenses/{id}/downloads
@desc Download videos
@required {id: str # The license ID of the item to (re)download. The download links in the response are valid for 8 hours.}
@optional {auth_cookie: map{name!: str, value!: str} # (Deprecated), show_modal: bool # (Deprecated), size: str(web/sd/hd/4k) # Size of the video, verification_code: str # (Deprecated)}
@returns(200) {url: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}
@example_request {"size":"web"}

@endpoint POST /v2/videos/collections
@desc Create video collections
@required {name: str # The name of the collection}
@returns(201) {id: str} # Successfully created video collection
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}
@example_request {"name":"Test Collection 19cf"}

@endpoint GET /v2/videos/collections
@desc List video collections
@optional {page: int=1 # Page number, per_page: int=100 # Number of results per page, embed: [str] # Which sharing information to include in the response, such as a URL to the collection}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/videos/collections/{id}
@desc Get the details of video collections
@required {id: str # The ID of the collection to return}
@optional {embed: [str] # Which sharing information to include in the response, such as a URL to the collection, share_code: str # Code to retrieve a shared collection}
@returns(200) {cover_item: map{added_time: str(date-time), id: str, media_type: str}, created_time: str(date-time), id: str, items_updated_time: str(date-time), name: str, share_code: str, share_url: str, total_item_count: int, updated_time: str(date-time)} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Collection not found}

@endpoint POST /v2/videos/collections/{id}
@desc Rename video collections
@required {id: str # The ID of the collection to rename, name: str # The new name of the collection}
@returns(204) Successfully updated collection
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Collection not found}
@example_request {"name":"My collection with a new name"}

@endpoint DELETE /v2/videos/collections/{id}
@desc Delete video collections
@required {id: str # The ID of the collection to delete}
@returns(204) Successfully deleted collection
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Collection not found}

@endpoint GET /v2/videos/categories
@desc List video categories
@optional {language: str(ar/bg/bn/cs/da/de/el/en/es/fi/fr/gu/he/hi/hr/hu/id/it/ja/kn/ko/ml/mr/nb/nl/or/pl/pt/ro/ru/sk/sl/sv/ta/te/th/tr/uk/ur/vi/zh/zh-Hant) # Language for the keywords and categories in the response}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint POST /v2/videos/collections/{id}/items
@desc Add videos to collections
@required {id: str # The ID of the collection to which items should be added, items: [map{added_time: str(date-time), id!: str, media_type: str}] # List of items}
@returns(204) Successfully added collection items
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Collection not found}
@example_request {"items":[{"id":"10120264"},{"id":"24419024"}]}

@endpoint GET /v2/videos/collections/{id}/items
@desc Get the contents of video collections
@required {id: str # Collection ID}
@optional {page: int=1 # Page number, per_page: int=100 # Number of results per page, share_code: str # Code to retrieve the contents of a shared collection, sort: str(newest/oldest)=oldest # Sort order}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Collection not found}

@endpoint DELETE /v2/videos/collections/{id}/items
@desc Remove videos from collections
@required {id: str # The ID of the Collection from which items will be deleted}
@optional {item_id: [str] # One or more video IDs to remove from the collection}
@returns(204) Successfully removed collection items
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Collection not found}

@endpoint GET /v2/videos/{id}/similar
@desc List similar videos
@required {id: str(asset-id) # The ID of a video for which similar videos should be returned}
@optional {language: str(ar/bg/bn/cs/da/de/el/en/es/fi/fr/gu/he/hi/hr/hu/id/it/ja/kn/ko/ml/mr/nb/nl/or/pl/pt/ro/ru/sk/sl/sv/ta/te/th/tr/uk/ur/vi/zh/zh-Hant) # Language for the keywords and categories in the response, page: int=1 # Page number, per_page: int=20 # Number of results per page, view: str(minimal/full)=minimal # Amount of detail to render in the response}
@returns(200) {data: [map], message: str, page: int, per_page: int, total_count: int, search_id: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/videos/updated
@desc List updated videos
@optional {start_date: str(date-or-date-time) # Show videos updated on or after the specified date. The API will default to UTC (00:00:00) if no specific time is provided, ensuring consistency., end_date: str(date-or-date-time) # Show videos updated before the specified date. The API will default to UTC (00:00:00) if no specific time is provided, ensuring consistency. Please note that the end date must be at least 5 minutes after the start date., interval: str=1 HOUR # Show videos updated in the specified time period, where the time period is an interval (like SQL INTERVAL) such as 1 DAY, 6 HOUR, or 30 MINUTE; the default is 1 HOUR, which shows videos that were updated in the hour preceding the request, page: int=1 # Page number, per_page: int=100 # Number of results per page, sort: str(newest/oldest)=newest # Sort by oldest or newest videos first}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK

@endgroup

@group audio
@endpoint GET /v2/audio/search
@desc Search for tracks
@optional {artists: [str] # Show tracks with one of the specified artist names or IDs, bpm: int # (Deprecated; use bpm_from and bpm_to instead) Show tracks with the specified beats per minute, bpm_from: int # Show tracks with the specified beats per minute or faster, bpm_to: int # Show tracks with the specified beats per minute or slower, duration: int # Show tracks with the specified duration in seconds, duration_from: int # Show tracks with the specified duration or longer in seconds, duration_to: int # Show tracks with the specified duration or shorter in seconds, genre: [str] # Show tracks with each of the specified genres; to get the list of genres, use `GET /v2/audio/genres`, is_instrumental: bool # Show instrumental music only, instruments: [str] # Show tracks with each of the specified instruments; to get the list of instruments, use `GET /v2/audio/instruments`, moods: [str] # Show tracks with each of the specified moods; to get the list of moods, use `GET /v2/audio/moods`, page: int=1 # Page number, per_page: int=20 # Number of results per page, query: str # One or more search terms separated by spaces, sort: str(score/ranking_all/artist/title/bpm/freshness/duration) # Sort by, sort_order: str(asc/desc)=desc # Sort order, vocal_description: str # Show tracks with the specified vocal description (male, female), view: str(minimal/full)=minimal # Amount of detail to render in the response, fields: str # Fields to display in the response; see the documentation for the fields parameter in the overview section, library: str(shutterstock/premier)=premier # Which library to search, language: str # Which language to search in}
@returns(200) {data: [map], message: str, page: int, per_page: int, total_count: int, search_id: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/audio/genres
@desc List audio genres
@optional {language: str # Which language the genres will be returned}
@returns(200) {data: [str]} # OK

@endpoint GET /v2/audio/instruments
@desc List audio instruments
@optional {language: str # Which language the instruments will be returned in}
@returns(200) {data: [str]} # OK

@endpoint GET /v2/audio/moods
@desc List audio moods
@optional {language: str # Which language the moods will be returned in}
@returns(200) {data: [str]} # OK

@endpoint GET /v2/audio
@desc List audio tracks
@required {id: [str] # One or more audio IDs}
@optional {view: str(minimal/full)=minimal # Amount of detail to render in the response, search_id: str # The ID of the search that is related to this request}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/audio/{id}
@desc Get details about audio tracks
@required {id: int # Audio track ID}
@optional {view: str(minimal/full)=full # Amount of detail to render in the response, search_id: str # The ID of the search that is related to this request}
@returns(200) {added_date: str(date), affiliate_url: str, album: map{id: str, title: str}, artists: [map], assets: map{album_art: map{file_size: int, url: str}, clean_audio: map{file_size: int, url: str}, original_audio: map{file_size: int, url: str}, preview_mp3: map{file_size: int, url: str}, preview_ogg: map{file_size: int, url: str}, waveform: map{file_size: int, url: str}, shorts_loops_stems: map{shorts: any, loops: any, stems: any}}, bpm: int, contributor: map{id: str}, deleted_time: str(date-time), description: str, duration: num, genres: [str], id: str, instruments: [str], is_adult: bool, is_instrumental: bool, isrc: str, keywords: [str], language: str, lyrics: str, media_type: str, model_releases: [map], moods: [str], published_time: str(date-time), recording_version: str, releases: [str], similar_artists: [map], submitted_time: str(date-time), title: str, updated_time: str(date-time), vocal_description: str, url: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint POST /v2/audio/licenses
@desc License audio tracks
@required {audio: [map{audio_id!: str, license: str, search_id: str}] # List of audio tracks to license}
@optional {license: str(audio_platform/premier_music_basic/premier_music_extended/premier_music_pro/premier_music_comp/asset_all_music) # License type, search_id: str # The ID of the search that led to licensing this track}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}
@example_request {"audio":[{"audio_id":"591623","license":"audio_platform","metadata":{"customer_id":"12345"}}]}

@endpoint GET /v2/audio/licenses
@desc List audio licenses
@optional {audio_id: str # Show licenses for the specified track ID, license: str # Restrict results by license., page: int=1 # Page number, per_page: int=20 # Number of results per page, sort: str(newest/oldest)=newest # Sort order, username: str # Filter licenses by username of licensee, start_date: str(date-time) # Show licenses created on or after the specified date, end_date: str(date-time) # Show licenses created before the specified date, download_availability: str(all/downloadable/non_downloadable)=all # Filter licenses by download availability, team_history: bool=false # Set to true to see license history for all members of your team.}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint POST /v2/audio/licenses/{id}/downloads
@desc Download audio tracks
@required {id: str # License ID}
@returns(200) {url: str, shorts_loops_stems: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint POST /v2/audio/collections
@desc Create audio collections
@required {name: str # The name of the collection}
@returns(201) {id: str} # Successfully created audio collection
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}
@example_request {"name":"Best rock music"}

@endpoint GET /v2/audio/collections
@desc List audio collections
@optional {page: int=1 # Page number, per_page: int=100 # Number of results per page, embed: [str] # Which sharing information to include in the response, such as a URL to the collection}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/audio/collections/{id}
@desc Get the details of audio collections
@required {id: str # Collection ID}
@optional {embed: [str] # Which sharing information to include in the response, such as a URL to the collection, share_code: str # Code to retrieve a shared collection}
@returns(200) {cover_item: map{added_time: str(date-time), id: str, media_type: str}, created_time: str(date-time), id: str, items_updated_time: str(date-time), name: str, share_code: str, share_url: str, total_item_count: int, updated_time: str(date-time)} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Collection not found}

@endpoint POST /v2/audio/collections/{id}
@desc Rename audio collections
@required {id: str # Collection ID, name: str # The new name of the collection}
@returns(204) Successfully updated collection
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Collection not found}
@example_request {"name":"Best rock music"}

@endpoint DELETE /v2/audio/collections/{id}
@desc Delete audio collections
@required {id: str # Collection ID}
@returns(204) Successfully deleted collection
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Collection not found}

@endpoint POST /v2/audio/collections/{id}/items
@desc Add audio tracks to collections
@required {id: str # Collection ID, items: [map{added_time: str(date-time), id!: str, media_type: str}] # List of items}
@returns(204) Successfully added collection items
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Collection not found}
@example_request {"items":[{"id":"442583"},{"id":"7491192"}]}

@endpoint GET /v2/audio/collections/{id}/items
@desc Get the contents of audio collections
@required {id: str # Collection ID}
@optional {page: int=1 # Page number, per_page: int=100 # Number of results per page, share_code: str # Code to retrieve the contents of a shared collection, sort: str(newest/oldest)=oldest # Sort order}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Collection not found}

@endpoint DELETE /v2/audio/collections/{id}/items
@desc Remove audio tracks from collections
@required {id: str # Collection ID}
@optional {item_id: [str] # One or more item IDs to remove from the collection}
@returns(204) Successfully removed collection items
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Collection not found}

@endgroup

@group sfx
@endpoint GET /v2/sfx/search
@desc Search for sound effects
@optional {added_date: str(date) # Show sound effects added on the specified date, added_date_start: str(date) # Show sound effects added on or after the specified date, added_date_end: str(date) # Show sound effects added before the specified date, duration: int # Show sound effects with the specified duration in seconds, duration_from: int # Show sound effects with the specified duration or longer in seconds, duration_to: int # Show sound effects with the specified duration or shorter in seconds, page: int=1 # Page number, per_page: int=20 # Number of results per page, query: str # One or more search terms separated by spaces, safe: bool=true # Enable or disable safe search, sort: str(popular/newest/relevance/random/oldest)=popular # Sort by, view: str(minimal/full)=minimal # Amount of detail to render in the response, language: str(ar/bg/bn/cs/da/de/el/en/es/fi/fr/gu/he/hi/hr/hu/id/it/ja/kn/ko/ml/mr/nb/nl/or/pl/pt/ro/ru/sk/sl/sv/ta/te/th/tr/uk/ur/vi/zh/zh-Hant) # Set query and result language (uses Accept-Language header if not set)}
@returns(200) {data: [map], message: str, page: int, per_page: int, total_count: int, search_id: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 503: Service Unavailable}

@endpoint GET /v2/sfx/{id}
@desc Get details about sound effects
@required {id: int # Audio track ID}
@optional {language: str(ar/bg/bn/cs/da/de/el/en/es/fi/fr/gu/he/hi/hr/hu/id/it/ja/kn/ko/ml/mr/nb/nl/or/pl/pt/ro/ru/sk/sl/sv/ta/te/th/tr/uk/ur/vi/zh/zh-Hant) # Language for the keywords and categories in the response, view: str(minimal/full)=minimal # Amount of detail to render in the response, library: str(shutterstock/premier/premiumbeat) # Which library to fetch from, search_id: str # The ID of the search that is related to this request}
@returns(200) {added_date: str(date), affiliate_url: str, artist: str, assets: map{preview_mp3: map{file_size: int, url: str}, waveform: map{file_size: int, url: str}}, contributor: map{id: str}, description: str, duration: num, id: str, keywords: [str], media_type: str, releases: [str], title: str, updated_time: str(date-time), url: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 503: Service Unavailable}

@endpoint GET /v2/sfx
@desc List details about sound effects
@required {id: [str(asset-id)] # One or more sound effect IDs}
@optional {view: str(minimal/full)=minimal # Amount of detail to render in the response, language: str(ar/bg/bn/cs/da/de/el/en/es/fi/fr/gu/he/hi/hr/hu/id/it/ja/kn/ko/ml/mr/nb/nl/or/pl/pt/ro/ru/sk/sl/sv/ta/te/th/tr/uk/ur/vi/zh/zh-Hant) # Language for the keywords and categories in the response, library: str(shutterstock/premier/premiumbeat) # Which library to fetch from, search_id: str # The ID of the search that is related to this request}
@returns(200) {data: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/sfx/licenses
@desc List sound effects licenses
@optional {sfx_id: str # Show licenses for the specified sound effects ID, license: str # Show sound effects that are available with the specified license, such as `standard` or `enhanced`, page: int=1 # Page number, per_page: int=20 # Number of results per page, sort: str(newest/oldest)=newest # Sort order, username: str # Filter licenses by username of licensee, start_date: str(date-time) # Show licenses created on or after the specified date, end_date: str(date-time) # Show licenses created before the specified date, license_id: str # Filter by the license ID, download_availability: str(all/downloadable/non_downloadable)=all # Filter licenses by download availability, team_history: bool=false # Set to true to see license history for all members of your team.}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint POST /v2/sfx/licenses
@desc License sound effects
@required {sound_effects: [map{sfx_id!: str, audio_layout: str, format: str, search_id: str, subscription_id!: str}] # Sound effects to license for}
@returns(200) {data: [map], errors: [map], message: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}
@example_request {"sound_effects":[{"format":"wav","sfx_id":"123456789","metadata":{"customer_id":"12345","geo_location":"US","number_viewed":"15","search_term":"dog"},"show_modal":true,"size":"ambisonic","subscription_id":"s12345678"}]}

@endpoint POST /v2/sfx/licenses/{id}/downloads
@desc Download sound effects
@required {id: str # License ID}
@returns(200) {url: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endgroup

@group editorial
@endpoint GET /v2/editorial/images/search
@desc Search editorial images
@required {country: str(country-code-3) # Show only editorial content that is available for distribution in a certain country}
@optional {query: str # One or more search terms separated by spaces, sort: str(relevant/newest/oldest)=relevant # Sort by, category: str # Show editorial content with each of the specified editorial categories; specify category names in a comma-separated list, supplier_code: [str] # Show only editorial content from certain suppliers, date_start: str(date) # Show only editorial content generated on or after a specific date, date_end: str(date) # Show only editorial content generated on or before a specific date, per_page: int=20 # Number of results per page, cursor: str # The cursor of the page with which to start fetching results; this cursor is returned from previous requests}
@returns(200) {data: [map], message: str, next: str, page: int, per_page: int, prev: str, search_id: str, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable}

@endpoint GET /v2/editorial/images/categories
@desc List editorial categories
@returns(200) {data: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/editorial/images/updated
@desc List updated content
@required {type: str(edit/addition) # Specify `addition` to return only images that were added or `edit` to return only images that were edited or deleted, date_updated_start: str(date-time) # Show images images added, edited, or deleted after the specified date. Acceptable range is 1970-01-01T00:00:01 to 2038-01-19T00:00:00., date_updated_end: str(date-time) # Show images images added, edited, or deleted before the specified date. Acceptable range is 1970-01-01T00:00:01 to 2038-01-19T00:00:00., country: str(country-code-3) # Show only editorial content that is available for distribution in a certain country}
@optional {date_taken_start: str(date) # Show images that were taken on or after the specified date; use this parameter if you want recently created images from the collection instead of updated older assets, date_taken_end: str(date) # Show images that were taken before the specified date, cursor: str # The cursor of the page with which to start fetching results; this cursor is returned from previous requests, sort: str(newest/oldest)=newest # Sort by, supplier_code: [str] # Show only editorial content from certain suppliers, per_page: int=500 # Number of results per page}
@returns(200) {data: [map], message: str, next: str, per_page: int, prev: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable}

@endpoint GET /v2/editorial/images/{id}
@desc Get editorial content details
@required {id: str # Editorial ID, country: str(country-code-3) # Returns only if the content is available for distribution in a certain country}
@returns(200) {aspect: num, assets: map{original: map{display_name: str, dpi: int, file_size: int, format: str, height: int, is_licensable: bool, width: int}, thumb_170: map{height: int, url: str, width: int}, thumb_220: map{height: int, url: str, width: int}, watermark_450: map{height: int, url: str, width: int}, watermark_1500: map{height: int, url: str, width: int}, small_jpg: map{display_name: str, dpi: int, file_size: int, format: str, height: int, is_licensable: bool, width: int}, medium_jpg: map{display_name: str, dpi: int, file_size: int, format: str, height: int, is_licensable: bool, width: int}}, byline: str, caption: str, categories: [map], date_taken: str(date), description: str, id: str, keywords: [str], special_instructions: str, title: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found}

@endpoint GET /v2/editorial/images
@desc list editorial image details
@required {id: [str] # ID of the editorial image to list details for, country: str(country-code-3) # Show only editorial image content that is available for distribution in a certain country}
@optional {search_id: str # The ID of the search that is related to this request}
@returns(200) {data: [map], search_id: str, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/editorial/images/licenses
@desc List editorial image licenses
@optional {image_id: str # Show licenses for the specified editorial image ID, license: str # Show editorial images that are available with the specified license name, page: int=1 # Page number, per_page: int=20 # Number of results per page, sort: str(newest/oldest)=newest # Sort order, username: str # Filter licenses by username of licensee, start_date: str(date-time) # Show licenses created on or after the specified date, end_date: str(date-time) # Show licenses created before the specified date, download_availability: str(all/downloadable/non_downloadable)=all # Filter licenses by download availability, team_history: bool=false # Set to true to see license history for all members of your team.}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint POST /v2/editorial/images/licenses
@desc License editorial content
@required {country: any # Mandatory country code for where the editorial content will be distributed; this value is used for rights checks, editorial: [map{editorial_id!: str, license!: str, metadata: map, size: str}] # Editorial content to license}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable}
@example_request {"country":"USA","editorial":[{"editorial_id":"10687730b","license":"premier_editorial_comp","metadata":{"customer_id":"12345","geo_location":"US","number_viewed":"15","search_term":"dog"},"size":"original"}]}

@endpoint GET /v2/editorial/images/livefeeds
@desc Get editorial livefeed list
@required {country: str(country-code-3) # Returns only livefeeds that are available for distribution in a certain country}
@optional {page: int=1 # Page number, per_page: int=20 # Number of results per page}
@returns(200) {data: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found}

@endpoint GET /v2/editorial/images/livefeeds/{id}
@desc Get editorial livefeed
@required {id: str # Editorial livefeed ID; must be an URI encoded string, country: str(country-code-3) # Returns only if the livefeed is available for distribution in a certain country}
@returns(200) {cover_item: map{height: int, id: str, url: str, width: int}, created_time: str(date-time), id: str, name: str, total_item_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found}

@endpoint GET /v2/editorial/images/livefeeds/{id}/items
@desc Get editorial livefeed items
@required {id: str # Editorial livefeed ID; must be an URI encoded string, country: str(country-code-3) # Returns only if the livefeed items are available for distribution in a certain country}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found}

@endpoint GET /v2/editorial/videos/search
@desc Search editorial video content
@required {country: str(country-code-3) # Show only editorial video content that is available for distribution in a certain country}
@optional {query: str # One or more search terms separated by spaces, sort: str(relevant/newest/oldest)=relevant # Sort by, category: str # Show editorial content with each of the specified editorial categories; specify category names in a comma-separated list, supplier_code: [str] # Show only editorial video content from certain suppliers, date_start: str(date) # Show only editorial video content generated on or after a specific date, date_end: str(date) # Show only editorial video content generated on or before a specific date, resolution: str(4k/high_definition/standard_definition) # Show only editorial video content with specific resolution, fps: num # Show only editorial video content generated with specific frames per second, per_page: int=20 # Number of results per page, cursor: str # The cursor of the page with which to start fetching results; this cursor is returned from previous requests}
@returns(200) {data: [map], message: str, next: str, page: int, per_page: int, prev: str, search_id: str, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable}

@endpoint GET /v2/editorial/videos/categories
@desc List editorial video categories
@returns(200) {data: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/editorial/videos/{id}
@desc Get editorial video content details
@required {id: str # Editorial ID, country: str(country-code-3) # Returns only if the content is available for distribution in a certain country}
@optional {search_id: str # The ID of the search that is related to this request}
@returns(200) {aspect: num, assets: map{original: map{display_name: str, file_size: int, format: str, fps: num, height: int, is_licensable: bool, width: int}, preview_mp4: map{url: str}, preview_webm: map{url: str}, thumb_jpg: map{url: str}}, byline: str, caption: str, categories: [map], date_taken: str(date), description: str, id: str, keywords: [str], title: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable}

@endpoint GET /v2/editorial/videos
@desc List editorial videos details by ID list
@required {id: [str] # ID of the editorial video to list details for, country: str(country-code-3) # Show only editorial video content that is available for distribution in a certain country}
@optional {search_id: str # The ID of the search that is related to this request}
@returns(200) {data: [map], search_id: str, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/editorial/videos/licenses
@desc List editorial video licenses
@optional {video_id: str # Show licenses for the specified editorial video ID, license: str # Show editorial videos that are available with the specified license name, page: int=1 # Page number, per_page: int=20 # Number of results per page, sort: str(newest/oldest)=newest # Sort order, username: str # Filter licenses by username of licensee, start_date: str(date-time) # Show licenses created on or after the specified date, end_date: str(date-time) # Show licenses created before the specified date, download_availability: str(all/downloadable/non_downloadable)=all # Filter licenses by download availability, team_history: bool=false # Set to true to see license history for all members of your team.}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint POST /v2/editorial/videos/licenses
@desc License editorial video content
@required {country: any # Mandatory country code for where the editorial content will be distributed; this value is used for rights checks, editorial: [map{editorial_id!: str, license!: str, metadata: map, size: str}] # Editorial content to license}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}
@example_request {"country":"USA","editorial":[{"editorial_id":"10679854a","license":"premier_editorial_video_digital_only","metadata":{"purchase_order":"12345"},"size":"original"}]}

@endgroup

@group cv
@endpoint POST /v2/cv/images
@desc Upload images
@required {base64_image: str # A Base 64 encoded jpeg or png; images can be no larger than 10mb and can be no larger than 10,000 pixels in width or height}
@returns(201) {upload_id: str} # Created
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 413: Payload Too Large, 415: Unsupported Media Type}
@example_request {"base64_image":"R0lGODlhgACAAPcAAEwiBLyaLOzNUNmWFNjOrNSuN7x6PPzqeOTMgfKSDMyuTPzwsdi2dHwuBPzbVu"}

@endpoint GET /v2/cv/similar/images
@desc List similar images
@required {asset_id: str # The asset ID or upload ID to find similar images for}
@optional {license: [str]=commercial # Show only images with the specified license, safe: bool=true # Enable or disable safe search, language: str(ar/bg/bn/cs/da/de/el/en/es/fi/fr/gu/he/hi/hr/hu/id/it/ja/kn/ko/ml/mr/nb/nl/or/pl/pt/ro/ru/sk/sl/sv/ta/te/th/tr/uk/ur/vi/zh/zh-Hant) # Language for the keywords and categories in the response, page: int=1 # Page number, per_page: int=20 # Number of results per page, view: str(minimal/full)=minimal # Amount of detail to render in the response}
@returns(200) {data: [map], message: str, page: int, per_page: int, search_id: str, spellcheck_info: map, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/cv/similar/videos
@desc List similar videos
@required {asset_id: str # The asset ID or upload ID to find similar videos for}
@optional {license: [str]=commercial # Show only videos with the specified license, safe: bool=true # Enable or disable safe search, language: str(ar/bg/bn/cs/da/de/el/en/es/fi/fr/gu/he/hi/hr/hu/id/it/ja/kn/ko/ml/mr/nb/nl/or/pl/pt/ro/ru/sk/sl/sv/ta/te/th/tr/uk/ur/vi/zh/zh-Hant) # Language for the keywords and categories in the response, page: int=1 # Page number, per_page: int=20 # Number of results per page, view: str(minimal/full)=minimal # Amount of detail to render in the response}
@returns(200) {data: [map], message: str, page: int, per_page: int, total_count: int, search_id: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/cv/keywords
@desc List suggested keywords
@required {asset_id: any # The asset ID or upload ID to suggest keywords for}
@returns(200) {data: [str], errors: [map], message: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 415: Unsupported Media Type}

@endgroup

@group catalog
@endpoint GET /v2/catalog/search
@desc Search catalogs for assets
@optional {sort: str(newest/oldest)=newest # Sort by, page: int=1 # Page number, per_page: int=20 # Number of results per page, query: str # One or more search terms separated by spaces, collection_id: [str] # Filter by collection id, asset_type: [str] # Filter by asset type}
@returns(200) {page: num, per_page: num, total_count: num, data: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/catalog/collections
@desc List catalog collections
@optional {page: int=1 # Page number, per_page: int=20 # Number of results per page, sort: str(newest/oldest)=newest # Sort by, shared: bool=false # Set to true to omit collections that you own and return only collections  that are shared with you}
@returns(200) {page: num, per_page: num, total_count: num, data: [map]} # OK
@errors {400: Invalid status value}

@endpoint POST /v2/catalog/collections
@desc Create catalog collections
@required {name: str}
@optional {visibility: str(private/public)=private, items: [map{asset!: map}]}
@returns(201) {id: str, name: str, cover_asset: map{id: str, asset: map{id: str, type: str, name: str}, created_time: str(date-time), collection_ids: [str]}, total_item_count: num, created_time: str(date-time), updated_time: str(date-time), visibility: str, role_assignments: map{collection_id: str, roles: map{owners: [map], editors: [map], viewers: [map]}}} # OK
@example_request {"name":"New Collection","visibility":"public","items":[{"asset":{"id":"1690105108","type":"image"}}]}

@endpoint PATCH /v2/catalog/collections/{collection_id}
@desc Update collection metadata
@required {collection_id: str # ID of collection that needs to be modified}
@optional {name: str, visibility: str(private/public), cover_asset: map{id!: str}}
@returns(200) {id: str, name: str, cover_asset: map{id: str, asset: map{id: str, type: str, name: str}, created_time: str(date-time), collection_ids: [str]}, total_item_count: num, created_time: str(date-time), updated_time: str(date-time), visibility: str, role_assignments: map{collection_id: str, roles: map{owners: [map], editors: [map], viewers: [map]}}} # OK
@example_request {"name":"My Collection","visibility":"public","cover_asset":{"id":"123"}}

@endpoint DELETE /v2/catalog/collections/{collection_id}
@desc Delete catalog collections
@required {collection_id: str # The ID of the collection to delete}
@returns(204) OK
@errors {404: Collection not found}

@endpoint POST /v2/catalog/collections/{collection_id}/items
@desc Add items to catalog collections
@required {collection_id: str # The ID of the collection to add assets to, items: [map{asset!: map}]}
@returns(200) {id: str, name: str, cover_asset: map{id: str, asset: map{id: str, type: str, name: str}, created_time: str(date-time), collection_ids: [str]}, total_item_count: num, created_time: str(date-time), updated_time: str(date-time), visibility: str, role_assignments: map{collection_id: str, roles: map{owners: [map], editors: [map], viewers: [map]}}} # OK
@example_request {"items":[{"asset":{"id":"1690105108","type":"image"}}]}

@endpoint DELETE /v2/catalog/collections/{collection_id}/items
@desc Remove items from catalog collection
@required {collection_id: str # The ID of the collection to remove assets from, items: [map{id!: str}]}
@returns(200) {id: str, name: str, cover_asset: map{id: str, asset: map{id: str, type: str, name: str}, created_time: str(date-time), collection_ids: [str]}, total_item_count: num, created_time: str(date-time), updated_time: str(date-time), visibility: str, role_assignments: map{collection_id: str, roles: map{owners: [map], editors: [map], viewers: [map]}}} # OK
@example_request {"items":[{"id":"123"}]}

@endgroup

@group contributors
@endpoint GET /v2/contributors
@desc Get details about multiple contributors
@required {id: [str] # One or more contributor IDs}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/contributors/{contributor_id}
@desc Get details about a single contributor
@required {contributor_id: str # Contributor ID}
@returns(200) {about: str, contributor_type: [str], display_name: str, equipment: [str], id: str, location: str, portfolio_url: str, social_media: map{facebook: str, google_plus: str, linkedin: str, pinterest: str, tumblr: str, twitter: str}, styles: [str], subjects: [str], website: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/contributors/{contributor_id}/collections
@desc List contributors' collections
@required {contributor_id: str # Contributor ID}
@optional {sort: str(newest/last_updated/item_count) # Sort order}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Contributor not found}

@endpoint GET /v2/contributors/{contributor_id}/collections/{id}
@desc Get details about contributors' collections
@required {contributor_id: str # Contributor ID, id: str # Collection ID that belongs to the contributor}
@returns(200) {cover_item: map{added_time: str(date-time), id: str, media_type: str}, created_time: str(date-time), id: str, items_updated_time: str(date-time), name: str, share_code: str, share_url: str, total_item_count: int, updated_time: str(date-time)} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Set not found}

@endpoint GET /v2/contributors/{contributor_id}/collections/{id}/items
@desc Get the items in contributors' collections
@required {contributor_id: str # Contributor ID, id: str # Collection ID that belongs to the contributor}
@optional {page: int=1 # Page number, per_page: int=20 # Number of results per page, sort: str(newest/oldest) # Sort order}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Set not found}

@endgroup

@group user
@endpoint GET /v2/user
@desc Get user details
@returns(200) {contributor_id: str, customer_id: str, email: str, first_name: str, full_name: str, id: str, is_premier: bool, is_premier_parent: bool, language: str, last_name: str, only_enhanced_license: bool, only_sensitive_use: bool, organization_id: str, premier_permissions: [str], username: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/user/access_token
@desc Get access token details
@returns(200) {client_id: str, contributor_id: str, customer_id: str, expires_in: int, organization_id: str, realm: str, scopes: [str], user_id: str, username: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/user/subscriptions
@desc List user subscriptions
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endgroup

@group test
@endpoint GET /v2/test
@desc Echo text
@optional {text: str=ok # Text to echo}
@returns(200) {text: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/test/validate
@desc Validate input
@required {id: int # Integer ID}
@optional {tag: [str] # List of tags, user-agent: str # User agent}
@returns(200) {header: map{user-agent: str}, query: map{id: int, tag: [str]}} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endgroup

@group oauth
@endpoint GET /v2/oauth/authorize
@desc Authorize applications
@required {client_id: str # Client ID (Consumer Key) of your application, redirect_uri: str # The callback URI to send the request to after authorization; must use a host name that is registered with your application, response_type: str # Type of temporary authorization code that will be used to generate an access code; the only valid value is 'code', state: str # Unique value used by the calling app to verify the request}
@optional {realm: str(customer/contributor)=customer # User type to be authorized (usually 'customer'), scope: str=user.view # Space-separated list of scopes to be authorized}
@errors {302: Redirect user to authenticate with Shutterstock, 400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint POST /v2/oauth/access_token
@desc Get access tokens
@required {client_id: str # Client ID (Consumer Key) of your application, grant_type: str(authorization_code/client_credentials/refresh_token) # Grant type: authorization_code generates user tokens, client_credentials generates short-lived client grants}
@optional {client_secret: str # Client Secret (Consumer Secret) of your application, code: str # Response code from the /oauth/authorize flow; required if grant_type=authorization_code, realm: str(customer/contributor)=customer # User type to be authorized (usually 'customer'), expires: bool=false # Whether or not the token expires, expiring tokens come with a refresh_token to renew the access_token, refresh_token: str # Pass this along with grant_type=refresh_token to get a fresh access token}
@returns(200) {access_token: str, expires_in: int, token_type: str, refresh_token: str, user_token: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}
@example_request {"client_id":"141024g14g28104gff1h"}

@endgroup

@group editorial
@endpoint GET /v2/editorial/{id}
@desc (Deprecated) Get editorial content details
@required {id: str # Editorial ID, country: str(country-code-3) # Returns only if the content is available for distribution in a certain country}
@optional {search_id: str # The ID of the search that is related to this request}
@returns(200) {aspect: num, assets: map{original: map{display_name: str, dpi: int, file_size: int, format: str, height: int, is_licensable: bool, width: int}, thumb_170: map{height: int, url: str, width: int}, thumb_220: map{height: int, url: str, width: int}, watermark_450: map{height: int, url: str, width: int}, watermark_1500: map{height: int, url: str, width: int}, small_jpg: map{display_name: str, dpi: int, file_size: int, format: str, height: int, is_licensable: bool, width: int}, medium_jpg: map{display_name: str, dpi: int, file_size: int, format: str, height: int, is_licensable: bool, width: int}}, byline: str, caption: str, categories: [map], date_taken: str(date), description: str, id: str, keywords: [str], special_instructions: str, title: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 404: Not Found}

@endpoint POST /v2/editorial/licenses
@desc (Deprecated) License editorial content
@required {country: any # Mandatory country code for where the editorial content will be distributed; this value is used for rights checks, editorial: [map{editorial_id!: str, license!: str, metadata: map, size: str}] # Editorial content to license}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable}
@example_request {"country":"USA","editorial":[{"editorial_id":"10687730b","license":"premier_editorial_comp","metadata":{"customer_id":"12345","geo_location":"US","number_viewed":"15","search_term":"dog"},"size":"original"}]}

@endpoint GET /v2/editorial/livefeeds
@desc (Deprecated) Get editorial livefeed list
@required {country: str(country-code-3) # Returns only livefeeds that are available for distribution in a certain country}
@optional {page: int=1 # Page number, per_page: int=20 # Number of results per page}
@returns(200) {data: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable}

@endpoint GET /v2/editorial/livefeeds/{id}
@desc (Deprecated) Get editorial livefeed
@required {id: str # Editorial livefeed ID; must be an URI encoded string, country: str(country-code-3) # Returns only if the livefeed is available for distribution in a certain country}
@returns(200) {cover_item: map{height: int, id: str, url: str, width: int}, created_time: str(date-time), id: str, name: str, total_item_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable}

@endpoint GET /v2/editorial/livefeeds/{id}/items
@desc (Deprecated) Get editorial livefeed items
@required {id: str # Editorial livefeed ID; must be an URI encoded string, country: str(country-code-3) # Returns only if the livefeed items are available for distribution in a certain country}
@returns(200) {data: [map], errors: [map], message: str, page: int, per_page: int, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable}

@endpoint GET /v2/editorial/search
@desc (Deprecated) Search editorial content
@required {country: str(country-code-3) # Show only editorial content that is available for distribution in a certain country}
@optional {query: str # One or more search terms separated by spaces, sort: str(relevant/newest/oldest)=relevant # Sort by, category: str # Show editorial content within a certain editorial category; specify by category name, supplier_code: [str] # Show only editorial content from certain suppliers, date_start: str(date) # Show only editorial content generated on or after a specific date, date_end: str(date) # Show only editorial content generated on or before a specific date, per_page: int=20 # Number of results per page, cursor: str # The cursor of the page with which to start fetching results; this cursor is returned from previous requests}
@returns(200) {data: [map], message: str, next: str, page: int, per_page: int, prev: str, search_id: str, total_count: int} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable}

@endpoint GET /v2/editorial/categories
@desc (Deprecated) List editorial categories
@returns(200) {data: [map]} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden}

@endpoint GET /v2/editorial/updated
@desc (Deprecated) List updated content
@required {type: str(edit/addition) # Specify `addition` to return only images that were added or `edit` to return only images that were edited or deleted, date_updated_start: str(date-time) # Show images images added, edited, or deleted after the specified date. Acceptable range is 1970-01-01T00:00:01 to 2038-01-19T00:00:00., date_updated_end: str(date-time) # Show images images added, edited, or deleted before the specified date. Acceptable range is 1970-01-01T00:00:01 to 2038-01-19T00:00:00., country: str(country-code-3) # Show only editorial content that is available for distribution in a certain country}
@optional {date_taken_start: str(date) # Show images that were taken on or after the specified date; use this parameter if you want recently created images from the collection instead of updated older assets, date_taken_end: str(date) # Show images that were taken before the specified date, cursor: str # The cursor of the page with which to start fetching results; this cursor is returned from previous requests, sort: str(newest/oldest)=newest # Sort by, supplier_code: [str] # Show only editorial content from certain suppliers, per_page: int=500 # Number of results per page}
@returns(200) {data: [map], message: str, next: str, per_page: int, prev: str} # OK
@errors {400: Bad Request, 401: Unauthorized, 403: Forbidden, 406: Not Acceptable}

@endgroup

@end
