https://cloud.51degrees.com/api/v4/json?resource=YOUR_KEY&user-agent=Mozilla/5.0 (co … Xbox; Xbox One)
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 98,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,276,202 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
The phone in their hand says what they'll spend
Price band, model, and device age are three things a shopper tells you before they've typed a word. Put them in your analytics and look at which devices fill the biggest baskets.
Who it serves. Merchandising and analytics teams.
Pairs well with Frictionless checkout, to turn shopper insights into faster, more personal checkouts.
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 What the shopper paid for their phone, which says a lot about what they'll pay you.
- Add device price band and model as dimensions in your analytics
- Correlate device value with basket size and conversion
- Change the promotions when the numbers say so
- Test, taste, repeat
Chef's tip. A shopper on a $1,200 phone and a shopper on a $120 phone see the same homepage. Should they?
The right asset for every screen, decided at serve time
Screen size, pixel density, and the video codecs the browser decodes decide whether a creative plays or stutters. Pick the format each device can show and the lightest file that fits the connection, and the ad gets watched to the end.
Who it serves. Ad ops and creative teams tired of one-size-fits-none.
Pairs well with The perfect stream, to deliver the right creative and the right stream, every time.
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 Direct commercial impact: better engagement and less wasted bandwidth.
- Measure the exact screen size and pixel density
- Check which video and image formats the device can actually decode
- Pick the creative variant to match
- Garnish with analytics and refine the next campaign
Chef's tip. Responsive design stretches one creative to fit all. This recipe cooks the right one in the first place.
High-value audiences, no cookies required
The device in someone's hand says whether they're a premium, mid-market, or budget buyer, and the network says where they are. Segment by price band, device age, and technology adoption, then add the country and town from the IP address. There's no behavioral data to collect or defend.
Who it serves. Media buyers targeting premium users after the third-party cookie.
Pairs well with Bidstream enrichment, to turn enriched bid requests into premium audience targeting.
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 It separates premium, mid-market, and budget consumers without needing any behavioral data.
- Reduce your traffic down to devices in a premium price band.
- Add ReleaseAge to find the flagships released this year.
- Season with country and town for market-level targeting.
- Serve premium creative to people who actually buy premium. Cap and measure with 51Did.
Chef's tip. Someone on a brand-new flagship and someone on a 2019 mid-ranger are not the same audience. Stop bidding like they are.
Know which screen is really behind the bid request
A bid request claims a smart TV and says what it can decode. NativeBrand and NativeModel name the manufacturer and model really behind it, and the chipset says what it truly decodes.
What changes. When the claim and the detection disagree, the inventory isn't what it says it is. Spoofed CTV inventory is flagged before you bid on it, and the budget stays with the screens that exist.
Who it serves. CTV publishers, SSPs, DSPs, and measurement platforms.
Pairs well with Suspicious traffic management, to stop fake CTV traffic, and with The perfect stream to optimize every genuine one.
Integration time. One sprint, alongside your bidder.
Ingredients, 12
- IsTv
- IsMediaHub
- IsConsole
- HardwareVendor
- HardwareModel
- NativeBrand
- NativeModel
- HardwareVideoCodecsDecode
- PlatformName
- PlatformVersion
- BrowserName
- DeviceType
Hero ingredient. NativeBrand The actual manufacturer of the device, not what the bid request claims. Immediate value against CTV spoofing.
- 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 what it can actually decode
- Measure and price by device, not by IP
Chef's tip. Fake CTV traffic never watches television. It just bills like it does.
Richer device data in every OpenRTB auction
Most bid requests arrive with the device half described. Client Hints froze the User-Agent, and a reduced User-Agent tells a bidder less every year. We put the make, model, screen, price band, and operating system back, with a verified 51Did, before the auction starts.
What changes. Bidders pay for what they can see, so bid density and CPMs rise.
"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, to turn richer bid requests into smarter header bidding.
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
- Fold the device properties and 51Did into the OpenRTB request
- Serve to bidders while hot
- Watch bid density and CPMs rise
Chef's tip. Client Hints froze the User-Agent. We didn't freeze with it.
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.