https://cloud.51degrees.com/api/v4/json?resource=YOUR_KEY&user-agent=Mozilla/5.0 (co … e.com/bot.html)
Legacy
Psst. What do you do when the regexes in that "free" script you picked up from a place you've forgotten break and you start losing money? 😫
Single feature. Missing the whole picture.
51Degrees
36 million downloads, 1.6 million websites, and 145,000 downloads in the last week.
Plans and prices are on the pricing page, and every property is in the Property Dictionary.
What you need to know
Follow the device detection tutorial for cloud or on-premise integration. For cloud use, read about the Resource Key, then create a Resource Key with the properties you need.
using (var pipeline = new DeviceDetectionPipelineBuilder(
loggerFactory)
.UseOnPremise(dataFile, null, false)
.SetPerformanceProfile(PerformanceProfiles.LowMemory)
.SetShareUsage(false)
.SetAutoUpdate(false)
.SetDataUpdateOnStartUp(false)
.SetDataFileSystemWatcher(false)
.Build())
{
using (var data = pipeline.CreateFlowData())
{
data.AddEvidence(evidence);
data.Process();
var device = data.Get<IDeviceData>();
}
}
using (var pipeline = new FiftyOnePipelineBuilder(
loggerFactory, serviceProvider)
.BuildFromConfiguration(pipelineOptions))
{
using (var data = pipeline.CreateFlowData())
{
data.AddEvidence(evidence);
data.Process();
var device = data.Get<IDeviceData>();
}
}
System.setProperty("TestDataFile", dataFileLocation);
PipelineOptions pipelineOptions =
PipelineOptionsFactory.getOptionsFromFile(optionsFile);
try (Pipeline pipeline = new FiftyOnePipelineBuilder()
.buildFromConfiguration(pipelineOptions)) {
try (FlowData data = pipeline.createFlowData()) {
data.addEvidence(evidence);
data.process();
DeviceData device = data.get(DeviceData.class);
}
}
try (Pipeline pipeline = new DeviceDetectionPipelineBuilder()
.useCloud(resourceKey)
.build()) {
try (FlowData data = pipeline.createFlowData()) {
data.addEvidence(evidence);
data.process();
DeviceData device = data.get(DeviceData.class);
}
}
const pipeline = new DeviceDetectionOnPremisePipelineBuilder({
dataFile,
performanceProfile: 'LowMemory',
shareUsage: false,
autoUpdate: false,
updateOnStart: false,
fileSystemWatcher: false
}).build();
const data = pipeline.createFlowData();
evidence.forEach((value, key, map) => {
data.evidence.add(key, value);
});
await data.process();
const device = data.device;
const pipeline = new PipelineBuilder()
.buildFromConfiguration(options);
const data = pipeline.createFlowData();
evidence.forEach((value, key, map) => {
data.evidence.add(key, value);
});
await data.process();
const device = data.device;
pipeline = DeviceDetectionPipelineBuilder(
data_file_path = data_file,
performance_profile = "MaxPerformance",
usage_sharing = False,
auto_update = False,
licence_keys = "").add_logger(logger).build()
with pipeline.create_flowdata() as data:
data.evidence.add_from_dict(evidence)
data.process()
device = data.device
pipeline = PipelineBuilder().add_logger(
logger).build_from_configuration(config)
data = pipeline.create_flowdata()
data.evidence.add_from_dict(evidence)
data.process()
device = data.device
$engine = new DeviceDetectionOnPremise([
'performanceProfile' => 'LowMemory',
]);
$pipeline = (new PipelineBuilder())
->add($engine)
->addLogger($logger)
->build();
$data = $pipeline->createFlowData();
$data->evidence->setArray($evidence);
$data->process();
$device = $data->device;
$pipeline = (new PipelineBuilder())
->addLogger($logger)
->buildFromConfig($config);
$data = $pipeline->createFlowData();
$data->evidence->setArray($evidence);
$data->process();
$device = $data->device;
let pipeline = DeviceDetectionPipelineBuilder::on_premise(
&options.data_file)
.performance_profile(options.profile)
.share_usage(false)
.auto_update(false)
.build()
.context(
"failed to build the on-premise device-detection pipeline")?;
let mut data = pipeline.create_flow_data_with(
Evidence::builder()
.add_all(pairs.iter().map(|(k, v)| (*k, *v)))
.build(),
);
data.process()
.context("on-premise pipeline processing failed")?;
let device = data
.get(DEVICE_DATA_KEY)
.context(
"the Hash engine should have produced device data")?;
let mut builder =
DeviceDetectionPipelineBuilder::cloud(options.resource_key);
if let Some(endpoint) = options.endpoint {
builder = builder.endpoint(endpoint);
}
let pipeline = builder
.share_usage(false)
.build()
.context(
"failed to build the cloud device-detection pipeline")?;
let mut data = pipeline.create_flow_data_with(
Evidence::builder()
.add_all(pairs.iter().map(|(k, v)| (*k, *v)))
.build(),
);
data.process().context("cloud pipeline processing failed")?;
match data.get(DEVICE_DATA_KEY) {
Some(device) => {
}
None => {
}
}
config := dd.NewConfigHash(dd.Default)
engine, err := onpremise.New(
onpremise.WithConfigHash(config),
onpremise.WithDataFile(params.DataFile),
onpremise.WithAutoUpdate(false),
)
results, err := engine.Process(evidence)
propertyName := "IsMobile"
value, err := results.ValuesString(
propertyName,
",")
StatusCode status = HashInitManagerFromFile(
&manager,
config,
&properties,
dataFilePath,
exception);
ResultsHash *results = ResultsHashCreate(&manager, 1);
EvidenceKeyValuePairArray* evidenceArray =
EvidenceCreate(evs->count);
for (uint32_t j = 0; j < evs->count; j++) {
EvidenceAddString(
evidenceArray,
evs->items[j].prefix,
evs->items[j].key,
evs->items[j].value);
}
ResultsHashFromEvidence(results, evidence, exception);
ResultsHashGetValuesString(
results,
propertyName,
valueBuffer,
valueBufferLength,
(char* const)",",
exception);
// The 51Degrees C library runs device detection
// inside your own program, so there is no cloud version.
// Choose On-premise for its example.
load_module %%MODULE_PATH%%modules/ngx_http_51D_module.so;
http {
51D_file_path %%FILE_PATH%%;
server {
location /hash {
51D_match_ua x-device BrowserName,PlatformName;
51D_match_ua_client_hints x-device-hinted
BrowserName,PlatformName;
51D_match_all x-mobile IsMobile;
add_header x-device $http_x_device;
add_header x-device-hinted $http_x_device_hinted;
add_header x-mobile $http_x_mobile;
}
}
}
# NGINX runs the 51Degrees C library for device detection
# inside the web server, so there is no cloud version.
# Choose On-premise for its example.
import fiftyonedegrees;
sub vcl_recv {
set req.http.X-IsMobile = fiftyonedegrees.match_single(
req.http.user-agent, "IsMobile");
}
sub vcl_deliver {
set resp.http.X-IsMobile = fiftyonedegrees.match_single(
req.http.user-agent, "IsMobile");
}
sub vcl_init {
fiftyonedegrees.start(
"/etc/varnish/51Degrees-LiteV4.1.hash");
}
# Varnish runs the 51Degrees C library for device detection
# inside the cache, so there is no cloud version.
# Choose On-premise for its example.
Compare the ways to deploy on the deployment options page.
- Your website (or content management system) receives a user's web page request.
- The API matches the request (User-Agents, other HTTP headers, and some optional JavaScript) to a device database.
- Use the returned properties to choose content for the device.
We match the User-Agent, Client-Hint, and other request evidence to device profiles in our database. Those profiles contain properties such as model, processing power, screen resolution, and retail price.
Apple devices leave the hardware model out of the User-Agent, so the request headers alone cannot tell one iPhone or iPad from another. Our client-side JavaScript gathers more evidence from the device, such as its screen resolution and graphics processor, and the API then returns the model, or the model group when several models give the same evidence.
It works even when an iPhone browses in desktop mode and reports itself as a Mac, or when an app such as Facebook changes the User-Agent.
Get IP intelligence and device detection properties in the same call.
{
"device": {
"hardwarevendor": "Apple",
"platformname": "iOS"
},
"ip": {
"country": "United Kingdom",
"connectiontype": "Broadband"
}
}
1.6 million websites have used 51Degrees Device Detection, and we report more than 99.99% accuracy. Ask us how that measure applies to the request evidence you can supply.
Our unmatched sub-millisecond performance gives you the edge, with 9,151,766 detections per second on a 128-core server. The API is ready to detect 142 milliseconds after it starts on an eight-core server. See the hardware benchmarks and the performance options.
We update our unrivaled 1,295,686 device combinations with a new data file every Monday through Friday, so you stay bang up to date. Read about data file updates.
% of active web sessions by device type
% of active web sessions by browser
We publish the latest graphs on our data quality page, and our processes are certified to ISO 9001 and ISO/IEC 27001. Learn more from our case studies.
Pick one to find out more
Each heading opens a short answer, with code, a diagram, or a figure, and a link to the documentation for more.

What is device detection from 51Degrees?
Why use device detection?
In this mobile-first, rich-media world, even the best responsive-designed websites and apps run into problems. Like when awkward screen sizes can't display a menu correctly. Or when older hardware takes minutes to load a page with one 10-second video ad.
What is device detection?
We match the User-Agent, Client-Hint, and other request evidence to device profiles in our database. Those profiles contain properties such as model, processing power, screen resolution, and retail price.
What you can use it for
You can use device detection for tailored user experiences, optimized page performance, smarter ad targeting, and sharper web analytics.
5 ways to use Device detection
Use device data to inform your promotions
Compare basket size and conversion across device price bands in your analytics. Include model and device age when you review the results, then use what you learn to choose promotions to test.
Who it serves. Merchandising and analytics teams.
Pairs well with Frictionless checkout, when you also want to reduce form filling at checkout.
Integration time. 30 minutes to add the dimensions to your analytics.
Ingredients, 10
- PriceBand
- ReleaseYear
- ReleaseAge
- HardwareModel
- HardwareName
- ScreenInchesDiagonal
- PixelRatio
- PlatformName
- PlatformVersion
- BrowserName
Hero ingredient. PriceBand Group visits by the device's price band to compare basket size and conversion.
- Add device price band and model as dimensions in your analytics
- Compare basket size and conversion across device price bands
- Choose promotions based on the sales patterns you find
- Test the promotions and review the results
Chef's tip. Before changing what visitors on $1,200 and $120 phones see, compare their basket sizes in your analytics.
Choose ad creative that works on the visitor's device
Choose a version that fits the screen and uses a video format the browser can play. A lighter file can help on a slower connection, where a larger ad may stutter before the viewer reaches the end.
Who it serves. Ad ops and creative teams adapting ads for different devices.
Pairs well with The perfect stream, to match the video stream as well as the ad creative.
Integration time. One sprint, alongside your ad server.
Ingredients, 12
- ScreenInchesDiagonal
- ScreenPixelsWidth
- PixelRatio
- BrowserVideoCodecsDecode
- Html5Video
- WebP
- BrowserName
- IsMobile
- IsTablet
- IsTv
- ConnectionType
- HumanConfidence
Hero ingredient. BrowserVideoCodecsDecode Use the browser's supported video formats to choose an ad it can play.
- Read the screen size and pixel density
- Check which video and image formats the device can decode
- Pick the creative variant to match
- Use campaign analytics to refine the creative choices for the next campaign
Chef's tip. Resizing an ad for the screen doesn't tell you whether the device can play the video.
Use device and location data to build audiences
Group visitors by the price band and age of their devices, then add country and town from the IP address. You can target these segments without collecting behavioral data.
Who it serves. Media buyers building audiences without third-party cookies.
Pairs well with Bidstream enrichment, when you want to include these audience details in bid requests.
Integration time. One afternoon with the Pipeline API.
Ingredients, 12
- PriceBand
- ReleaseAge
- ReleaseYear
- HardwareRank
- HardwareVendor
- DeviceType
- BrowserName
- PlatformName
- Country
- Town
- HumanConfidence
- 51Did
Hero ingredient. PriceBand Use the device's price band to build audience segments without collecting behavioral data.
- Select devices in a premium price band.
- Add ReleaseAge to find the flagships released this year.
- Add country and town for local targeting.
- Serve premium creative to this audience, then use 51Did to cap frequency and measure the campaign.
Chef's tip. A flagship released this year and a 2019 mid-range phone can belong in different audience segments.
Check the device behind a CTV bid request
A bid request may describe a smart TV even when it comes from another device. Use NativeBrand and NativeModel to check the manufacturer and model, then compare the claimed video support with HardwareVideoCodecsDecode.
Before you bid. Flag requests where the claimed device and the detected device disagree. This helps keep spend away from spoofed CTV inventory.
Who it serves. CTV publishers, SSPs, DSPs, and measurement platforms.
Pairs well with Suspicious traffic management, when you need to investigate suspicious requests. The perfect stream covers playback on genuine devices.
Integration time. One sprint, alongside your bidder.
Ingredients, 12
- IsTv
- IsMediaHub
- IsConsole
- HardwareVendor
- HardwareModel
- NativeBrand
- NativeModel
- HardwareVideoCodecsDecode
- PlatformName
- PlatformVersion
- BrowserName
- DeviceType
Hero ingredient. NativeBrand Use the detected manufacturer to check the device claimed in a CTV bid request.
- Separate the TVs from the sticks, boxes, and consoles
- Pass the real vendor and model into the CTV bid request
- Cross-check the claimed device against the video formats it supports
- Measure and price each impression using device data
Chef's tip. Compare the claimed TV with the detected device before you spend on the impression.
Richer device data in every OpenRTB auction
Most bid requests arrive without a full device description. We add the make and model, screen details, price band, and operating system, together with a verified 51Did, before the auction starts.
Bidders get more device detail. That extra context can increase bid density and CPMs.
"device": {
"devicetype": 4,
"make": "Samsung",
"model": "Galaxy S25",
"os": "Android",
"osv": "15",
"w": 1080,
"h": 2340
}
Who it serves. Publishers, SSPs, DSPs, and exchanges enriching the bidstream.
Pairs well with Prebid bidstream enrichment, for adding the device data through Prebid.
Integration time. One sprint in your bid path.
Ingredients, 17
- HardwareVendor
- HardwareModel
- DeviceType
- PlatformName
- PlatformVersion
- PlatformVendor
- BrowserName
- BrowserVersion
- NativeBrand
- NativeModel
- ScreenPixelsWidth
- ScreenPixelsHeight
- PixelRatio
- PriceBand
- ThirdPartyCookiesEnabled
- HumanConfidence
- 51Did
Hero ingredient. HumanConfidence Know how likely it is that a person will see your ad.
- Deploy the 51Degrees Pipeline API in your bid path
- Add the device properties and 51Did to the OpenRTB request
- Send the enriched request to bidders
- Track bid density and CPMs after adding the data
Chef's tip. A reduced User-Agent gives bidders less device detail. Add the missing context to the request.
Pick the one closest to your business challenge
The story is for you and the recipe for your engineers, with the properties they need and a link to create their Resource Key.