McAPI - Screenshot API with C#

C# sample code to capture website screenshots with the McAPI Screenshot REST API service. We provide a simple VS console app (VisualStudio 2019 or newer) that you can use for testing, download. The sample uses C# with .NET 5 but older .NET runtimes should work too. To parse the returned JSON, the sample project uses Newtonsoft Json which can be installed via the NuGet package manager. The console app targets Windows 10 but the C# code will compile and run on ASP .NET servers as well.

Requirements: A free RapidAPI account. Replace YOUR_API_KEY in the snippets below with your RapidAPI key.

All samples below work with the free tier of the API, see RapidAPI McAPI Screenshot Listing for available plans.

See the overview page for a reference that lists all available parameters and error codes.

Capture a website screenshot using C#

In the first sample, we take a screenshot of the Indiehackers website. All parameters relevant for the actual screenhot capture are in the payload-string which is added as content to the request. The payload-string is formatted as a C# verbatim string for better readability.

The device is set to Default (viewPort size = 1024x768px). With the storeExternal option set to "false", the screenshot will be returned as a base64 encoded JPEG.

The source code:

// C#
  
using Newtonsoft.Json;
using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace McAPI
{
    class Program
    {
        static async Task Main(string[] args)
        {

            string payload = @"
            {
                ""url"": ""https://indiehackers.com"",
                ""format"": ""jpeg"",
                ""storeExternal"": ""false"",
                ""devices"": [ ""Default"" ]
            }";

            using (var client = new HttpClient())
            {
                var request = new HttpRequestMessage
                {
                    Method = HttpMethod.Post,
                    RequestUri = new Uri("https://mcapi-screenshot.p.rapidapi.com/"),
                    Headers =
                    {
                        { "x-rapidapi-key", "YOUR_API_KEY" },
                        { "x-rapidapi-host", "mcapi-screenshot.p.rapidapi.com" },
                    },
                    Content = new StringContent(payload)
                    {
                        Headers =
                        {
                            ContentType = new MediaTypeHeaderValue("application/json")
                        }
                    }
                };

                using (var response = await client.SendAsync(request))
                {
                    response.EnsureSuccessStatusCode();
                    var body = await response.Content.ReadAsStringAsync();
                    ...
                }
            }
        }
    }
}

The response will be delivered as a JSON formatted string in body, see further below for sample code that shows how to parse the data:

{
  "service": "McAPI Screenshot Generator, https://mcapi.io",
  "version": "V1",
  "url": "https://indiehackers.com",
  "screenshots": [
    {
      "device": "Default",
      "screenshot": "data:image/jpeg;base64,/9j/4AAQSkZJRgAB ... 9yXvZG0pSuhyP/9k="
    }
  ]
}

McAPI Screenshot API - Sample screenshot with C#

The returned image from the Swift request:

Image of McAPI Screenshot API Sample Screenshot C#

Specifying devices

The Screenshot API contains a built-in database of over one hundred predefined devices and screen sizes. To get a list of all devices use the listDevices option, like so:

// C#
  
...

string payload = @"
{
    ""listDevices"": ""true""
}";

...

The API will now return an array of all known devices, here's an excerpt:

{
  "devices": [

    ...
  
    { "name": "iPhone 12 mini", "width": 375, "height": 812 },
    { "name": "iPhone 12 mini landscape", "width": 812, "height": 375 },
    { "name": "iPhone 12", "width": 390, "height": 844 },
    { "name": "iPhone 12 landscape", "width": 844, "height": 390 },
    { "name": "iPhone 12 Pro", "width": 390, "height": 844 },
    { "name": "iPhone 12 Pro landscape", "width": 844, "height": 390 },
    { "name": "iPhone 12 Pro Max", "width": 428, "height": 926 },
    { "name": "iPhone 12 Pro Max landscape", "width": 926, "height": 428 },

    ...
  ]
}

Internally, the API also maintains proper User Agent-strings for the respective device, not shown in the list.

Specifying a predefined device is simple, just set its name in the call. In this example we want the screenshot as it would appear on an iPhone 12:

// C#
  
...

let parameters = [
  "url": "https://mcapi.io",
  "devices" : [ "iPhone 12" ]
] as [String : Any]

...

The devices param is an array; to create multiple screenshots at once, specify additional devices (the current limit is five):

// C#
  
...

string payload = @"
{
    ""url"": ""https://indiehackers.com"",
    ""format"": ""jpeg"",
    ""storeExternal"": ""false"",
    ""devices"": [ ""iPhone 12"", ""iPhone 12 landscape"" ]
}";

...

Note that specifying multiple devices will cause the API to load the target URL for each device and then take a screenshot; this can take some time with "heavy" or slow sites and may cause your code to timeout; see the discussion on timeouts.

Specifying viewports

If none of the predefined devices and screen sizes are suitable for your application, you can specify your own viewport:

// C#
  
...

string payload = @"
{
    ""url"": ""https://mcapi.io"",
    ""format"": ""png"",
    ""viewPort"": { ""width"": 800, ""height"": 600 }
}";

...

This will create a screenshot with 800x600px; if a viewport is specified, the API will use a generic desktop User agent-string when loading the target URL.

Note that the viewPort option is ignored if a devices array is also specified.

Cookie consent banners and ad blocking

If so desired, the API can also automatically click the "Accept", "Accept all" or similar buttons on DSGVO / GDPR cookie warnings (Note that this feature is currently experimental, see discussion.)

Consider the CNBC website which we captured with these settings:

// C#
  
...

string payload = @"
{
    ""url"": ""https://cnbc.com"",
    ""format"": ""png"",
    ""storeExternal"": ""true"",
    ""devices"": [ ""Default"" ]
}";

...

Here's the screenshot. The site displays a very prominent banner:

Screenshot API - Cookie Consent Banner C Sharp

To capture the site without the cookie warning, set the cookie option to "true" like so:

// C#
  
...

string payload = @"
{
    ""url"": ""https://cnbc.com"",
    ""format"": ""png"",
    ""storeExternal"": ""true"",
    ""cookie"": ""true"",    
    ""devices"": [ ""Default"" ]
}";

...

The screenshot now shows the site without the banner.

Screenshot API - Clicked Cookie Banner and Ad with C Sharp

Blocking ads in screenshots

Sometimes you will want to take screenshots with ads, for instance to check ad placement or rotation. However, in most cases you want the screenshots to capture the site as intended by the designers, i.e. without any ads. The screenshot API comes with a built-in ad blocker, activate it from C# like so:

// C#
  
...

string payload = @"
{
    ""url"": ""https://cnbc.com"",
    ""format"": ""png"",
    ""storeExternal"": ""true"",
    ""cookie"": ""true"",  
    ""adblock"": ""true"",    
    ""devices"": [ ""Default"" ]
}";

...

The CNBC website without cookie warning and without ads:

Screenshot API - Clicked Cookie Banner and Ad blocked Sharp

The header-parameter - writing screenshots to a file with C# .NET

With the storeExternal option set to "false", the screenshot image is returned as a base64 encoded string. Per default, this string has prefix (or header) that describes the media type (or MIME) of the content.

Sample payload block for a screenshot, to be returned as a PNG:

// C#

...

string payload = @"
{
    ""url"": ""https://mcapi.io"",
    ""format"": ""png"",
    ""storeExternal"": ""false""
}";

...

The result will look like this, note the image/jpeg part:

{
  "service": "McAPI Screenshot Generator, https://mcapi.io",
  "version": "V1",
  "url": "https://mcapi.io",
  "screenshots": [
    {
      "device": "Default",
      "screenshot": "data:image/jpeg;base64,iVBORr/klmpqa2 ... 9yXvZG0pjjmSuhQmCC"
    }
  ]
}

To parse the returned JSON, we set up two auxiliary C# structs, Screenshot and Result, that declare the fields that the API returns. After decoding you can then directly set the "screenshot"-string as the src property of an img tag. This is particularly useful if you want to load screenshots into a webview, like so:

// C#

...

public class Screenshot
{
    public string device;
    public string screenshot;
}

public class Result
{
    public string service { get; set; }
    public string version { get; set; }
    public string url { get; set; }
    public Screenshot[] screenshots { get; set; }
}

...

using (var response = await client.SendAsync(request))
{
    response.EnsureSuccessStatusCode();
    var body = await response.Content.ReadAsStringAsync();

    // In production code you would wrap the Json parser in try / catch blocks
    // and iterate over the screenshots array
    var screenshot = JsonConvert.DeserializeObject<Result>(body).screenshots[0].screenshot;
    var img = "<img src=\"" + screenshot + "\"/>";
    Console.WriteLine(img);
}

...

The MIME header will make sure that the image data is interpreted correctly by the web view or browser. However, when writing the image data to a JPEG or PNG file, including the header would result in an invalid file. To create a screenshot image without the header, set the header option to "false", like so:

// C#

...

string payload = @"
{
    ""url"": ""https://mcapi.io"",
    ""format"": ""png"",
    ""header"": ""false"",
    ""storeExternal"": ""false""
}";

...

The returned screenshot image without header:

{
  "service": "McAPI Screenshot Generator, https://mcapi.io",
  "version": "V1",
  "url": "https://mcapi.io",
  "screenshots": [
    {
      "device": "Default",
      "screenshot": "iVBORr/klmpqa2 ... 9yXvZG0pjjmSuhQmCC"
    }
  ]
}

Now, all we have to do is decode the base64 string and then save the PNG to a file. Shown here as a complete example (this is essentially the contents of the provided VS project, see link in the introduction):

// C#

using Newtonsoft.Json;
using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace McAPI
{
    public class Screenshot
    {
        public string device;
        public string screenshot;
    }

    public class Result
    {
        public string service { get; set; }
        public string version { get; set; }
        public string url { get; set; }
        public Screenshot[] screenshots { get; set; }
    }

    class Program
    {
        static async Task Main(string[] args)
        {

            string payload = @"
            {
                ""url"": ""https://mcapi.io"",
                ""format"": ""png"",
                ""storeExternal"": ""false"",
                ""header"": ""false"",
                ""devices"": [ ""Default"" ]
            }";

            using (var client = new HttpClient())
            {
                var request = new HttpRequestMessage
                {
                    Method = HttpMethod.Post,
                    RequestUri = new Uri("https://mcapi-screenshot.p.rapidapi.com/"),
                    Headers =
                    {
                        { "x-rapidapi-key", "YOUR_API_KEY" },
                        { "x-rapidapi-host", "mcapi-screenshot.p.rapidapi.com" },
                    },
                    Content = new StringContent(payload)
                    {
                        Headers =
                        {
                            ContentType = new MediaTypeHeaderValue("application/json")
                        }
                    }
                };

                using (var response = await client.SendAsync(request))
                {
                    response.EnsureSuccessStatusCode();
                    var body = await response.Content.ReadAsStringAsync();

                    // In production code you would wrap the Json parser in try / catch blocks
                    // and iterate over the screenshots array
                    var screenshot = JsonConvert.DeserializeObject<Result>(body).screenshots[0].screenshot;
                    var png = Convert.FromBase64String(screenshot);
                    var desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
                    var path = Path.Combine(desktop, "screenshot.png");
                    File.WriteAllBytes(path, png);
                }
            }
        }
    }
}

Back to McAPI Screenshot API main page.