Use the pixabay images/video API with nodejs – 2023

Introduction

What is REST API?
A REST API is a way for different computer programs to communicate with each other over the internet. Think of it like a set of rules for how two programs should talk to each other. One program, called the “client,” sends a request to another program, called the “server,” asking for some information or to do something.

The server then sends a response back to the client with the information it requested or a message saying it completed the task. This way, different programs can work together to share information or perform tasks without having to know how the other program works. The code you’re going to write in NodeJS below will create your server.

I’ve used a telegram bot for the script’s output. You can use it to build the same or use it in a web app, etc.

Pixabay

Pixabay is quite a famous website to download/contribute photos that have a royalty-free license. They offer a REST API, through which we can get the relevant photos based on our search query, users, collection IDs, etc.

They support photos, images, illustrations, vectors, music, sound effects, gifs, and videos. However, music, sound effects, and gifs are not available via the API as of writing this article.
The quality of output is really good, as tons of photographers contribute, including me!

Code

There is an unofficial NodeJS wrapper available for Pixabay like pixabay-api, however, it was last updated 6 years ago at the time of writing so won’t recommend it. We are going to use the Axios library to make requests. You can use another one as per your preference.

So for the development, we’ll use the plain API by making GET requests. If you need more granular control you should go by the plain API.
Check out the above wrapper in case it’s updated.

Step 1: Get the Pixabay key

Go to the docs, and make sure you’re logged in. Once you scroll down a little your key will be displayed there. Copy it as it is required to make it work.

Step 2: Install the dependencies and code

npm i axios dotenv // dotenv for storing the API key in .env file

I’m updating this bot (@FreeStockPhotosBot) of mine which has over 8k+ users. Earlier it used the Unsplash source but they are shutting it down so pixabay is a great option.

const axios = require("axios");
const config = require("../../config"); // Abstracter for .env vars

// Base API endpoint- pixabay.com/api
let requestUrl = `https://pixabay.com/api/?key=${ config.pixabay_key }&q=${ searchQuery }&image_type=all&per_page=200`;

axios.get(requestUrl)
   .then(function (response) {
      // API is reatelimited to 100 requests/minute
     if(response.headers["x-ratelimit-remaining"]<=1){
       ctx.replyWithHTML(ctx.getString(ctx, 'error.too_many_requests'));
       return;
     }
     
// response.data.hits is an array containing the image's URL and other data in objects
// If no output is given, throw an error or tell the user

 if(response.data.hits.length<=0){
// As I'm using telegram bot for output, hence.
      ctx.replyWithHTML(ctx.getString(ctx, 'error.photo_not_found'));
 } else {
     // return the output image
     ctx.replyWithPhoto(response.data.hits[0].largeImageURL);
})
  .catch(function (error) {
    // handle errors
    console.error(error);
    ctx.replyWithHTML(ctx.getString(ctx, 'error.api_error'));
});

Response from the API after search:-

{
    "total":3448,
    "totalHits":500,
    "hits":[
        {
            "id":4763351,
            "pageURL":"https://pixabay.com/photos/lizard-multicoloured-head-view-4763351/",
            "type":"photo",
            "tags":"lizard, multicoloured, head",
            "previewURL":"https://cdn.pixabay.com/photo/2020/01/13/19/43/lizard-4763351_150.jpg",
            "previewWidth":150,
            "previewHeight":99,
            "webformatURL":"https://pixabay.com/get/g9b278744311ec9ef0fb335ca65c6c245771fdfdea89ebea95cacfef236567f95549258cd91bc0089a5f5cbc23258c0490ed6ccbddeff0f6d706097da0d48ec9c_640.jpg",
            "webformatWidth":640,
            "webformatHeight":426,
            "largeImageURL":"https://pixabay.com/get/gc1141ce2127169c4a96fa2cc814dfa1740487e76592f51a4a4912fccf2d370d68a6a503123cbbe4692842390da02d9be0b635292c49702f9d69176b73ca0095c_1280.jpg",
            "imageWidth":6000,
            "imageHeight":4000,
            "imageSize":8437076,
            "views":118959,
            "downloads":93726,
            "collections":407,
            "likes":390,
            "comments":167,
            "user_id":11109462,
            "user":"Anrita1705",
            "userImageURL":"https://cdn.pixabay.com/user/2019/11/05/14-32-28-269_250x250.jpg"
        },    {
        "id": 73424,
        ...
    },
    ...
]
}

To get the relevant output, add or remove the request parameters in the base API endpoint like: –

q – The search query, if removed returns all images randomly. Needs to be URL encoded or in plus case. (cute+cat)

per_page – Number of images returned per search query, maximum 200. Default at 20

image_type – Supports “all”, “photo”, “illustration”, and “vector”. “all” is the default.

editors_choice – “true” or “false”, Select images that have received an Editor’s Choice award. If you want variety and more options to choose from don’t use this.

Others are mentioned here in the docs.

Videos

Everything stays the same, but the API endpoint changes to –

https://pixabay.com/api/videos/

One additional parameter is added, as you may have guessed.
video_type – Accepted values: “all”, “film”, “animation”, Default is all.

The response changes a bit:

{
    "total":4157,
    "totalHits":500,
    "hits":[
        {
            "id":16453,
            "pageURL":"https://pixabay.com/videos/id-16453/",
            "type":"film",
            "tags":"poppy field, poppy, field",
            "duration":30,
            "picture_id":"704052428-6930a7c92798b82cc07f9f7484aa014d1d228616547b67ba6ebbc349718f6d1c-d",
            "videos":{
                "large":{
                    "url":"https://cdn.pixabay.com/vimeo/272487468/Poppy%20Field%20-%2016453.mp4?width=1920&hash=1ee8aaaf5ae47e727b9ea78058017dfc94c1cede",
                    "width":1920,
                    "height":1080,
                    "size":18717171
                },
                "medium":{
                    "url":"https://cdn.pixabay.com/vimeo/272487468/Poppy%20Field%20-%2016453.mp4?width=1280&hash=8fe1eb743a3396fbd3d03909169436941582e840",
                    "width":1280,
                    "height":720,
                    "size":9367155
                },
                "small":{
                    "url":"https://cdn.pixabay.com/vimeo/272487468/Poppy%20Field%20-%2016453.mp4?width=960&hash=ef4f805bc8fcdd934a022455349f7fa34451c8b1",
                    "width":960,
                    "height":540,
                    "size":5612220
                },
                "tiny":{
                    "url":"https://cdn.pixabay.com/vimeo/272487468/Poppy%20Field%20-%2016453.mp4?width=640&hash=81ef7d239875c8c6d9d66aafe2327a6429ff87b8",
                    "width":640,
                    "height":360,
                    "size":1885871
                }
            },
            "views":543818,
            "downloads":298102,
            "likes":1752,
            "comments":679,
            "user_id":4265448,
            "user":"adonyig",
            "userImageURL":"https://cdn.pixabay.com/user/2017/02/02/19-32-42-833_250x250.jpg"
        },

Changes are to be made to the above code for Videos to work.

...

// Base API endpoint- pixabay.com/api/videos
let requestUrl = `https://pixabay.com/api/videos?key=${ config.pixabay_key }&q=${ searchQuery }&video_type=all&per_page=200`;

...
  // return the output video
  ctx.replyWithVideo(response.data.hits[0].videos.large);
...

Conclusion

As far as I’ve used the pixabay’s service is very reliable and the output quality is great, thanks to the awesome photographers!

I hope they introduce access to music, sound effects, and gif. Meanwhile, check more posts development posts.

Give me follow on Twitter if this helped 🙂