WURFL Project

Q: What is the WURFL?
A:  WURFL = Wireless Universal Resource FiLe.
In 2001, when the name of the project was originally devised, the term 'wireless' indicated what the term 'mobile' indicates today.
WURFL is a DDR, or Device Description Repository, i.e. a database containing the profile of mobile devices. The ambition of the WURFL project is to model the properties of all reasonably popular mobile devices around the planet and provide a simple API to programmatically query the capability database, typically in real time, to create mobile sites and applications tailored to the features of the requesting device.
Since the goal of WURFL is to be available on as many platform as possible and technologically as open as possible, XML was chosen as the format to capture device data (every development platform can handle XML).
WURFL was created by Luca Passani in 2001. In 2006, Steve Kamerman created Tera-WURFL (now called WURFL DB API), which allowed to store device data in a relational Database (MySQL).
Luca and Steve are co-founders of ScientiaMobile, the company that offers professional tools and support around WURFL.
Back to top

Q: Where do I find the WURFL?
A: In short:
The WURFL Home Page

The most recent public version of the WURFL file is made available at:

Standard APIs

WURFL Cloud Clients can als be considered WURFL API, since they allow access to WURFL capabilities in real time, by accessing ScientiaMobile's WURFL offering

Finally, third-party WURFL APIs are available on the Internet. The correct functioning of these APIs is not guaranteed. Licensing issues should also be carefully evaluated when using a third-party API with the public WURFL update, since the repository license does not allow use with non-standard APIs.
Back to top

Q: What is a WURFL <device>?
A:  A WURFL <device> is an XML fragment that models a certain device. As a minimum, the device XML fragment contains the user agent string, the device ID (created by the WURFL maintainer according to certain conventions) and the fall_back attribute, which gives a way to infer more info about the device by referring to other devices.
In addition to this data, a device element may carry more information: A WURFL device with capabilities looks something like this:
<device user_agent="Nokia3100" actual_device_root="true" 
  <group id="product_info">
    <capability name="model_name" value="3100"/>
  <group id="xhtml_ui">
    <capability name="xhtml_format_as_css_property" value="true"/>
    <capability name="xhtml_supports_table_for_layout" value="true"/>
    <capability name="xhtml_supports_css_cell_table_coloring" value="true"/>
    <capability name="xhtml_readable_background_color1" value="#99CCFF"/>
    <capability name="xhtml_readable_background_color2" value="#FFFFFF"/>
  <group id="markup">
    <capability name="preferred_markup" value="html_wi_oma_xhtmlmp_1_0"/>
    <capability name="html_wi_w3_xhtmlbasic" value="true"/>
    <capability name="html_wi_oma_xhtmlmp_1_0" value="true"/>
<device> elements may also work as 'containers' meant to represent a common root for families of devices (for ex: blackberry_generic_ver5 for BlackBerry RIM OS 5). In that case, the device will come with a dummy UA string such as DO_NOT_MATCH_BLACKBERRY_5)

An introduction to WURFL is also provided as part of the WURFL contributor on-line help for the WURFL DB at db.scientiamobile.com.
Back to top

Q: What is a WURFL device <capability>?
A:  A device capability is an XML fragment which contains information about a specific feature of a given device (and all the devices falling back into it. Refer to the example in the previous answer to see what capabilities look like.
Back to top

Q: What is a WURFL device capability <group>?
A:  Groups are used to improve the readibility of the WURFL repository (wurfl.xml file) by humans. Don't be fooled, though. The WURFL capability namespace is flat and capability names MUST be unique across groups.
Back to top

Q: Where do I find capability X explained?
A:  There is a very nice document on the WURFL website which describes all the capabilities:

Back to top

Q: What is a device "fall back"?
A:  No newly-released wireless device is totally new when it comes to the software it runs, meaning that the same software was already running on older devices by the same manufacturer.
This fact can be exploited to make the WURFL more compact and to make reasonable guesses about the features of new devices. The fall_back mechanism achieves exactly this. By pointing to a different device (typically an older device by the same manufacturer), programming APIs can traverse the device hierarchy and figure out the capability of any device.
A more detailed explanation of how the fall_back works can be found at:
Back to top

Q: What is the 'generic' device?
A:  The 'generic' device is the first device at the top of the WURFL file and represents unrecognized devices, meaning that when a device cannot be matched against any device in the WURFL, it is guaranteed to match at least the generic device.
In addition, generic guarantees a termination point for all of the fall_back chains in the WURFL. 'generic' contains the definition of all capabilities. Its capabilities typically have minimalistic values (small screens, basic XHTML support, and so on). Of course, this implies that a WURFL file can potentially be broken way beyond what an XML Schema or DTD can protect you against. The WURFL maintainer has utilities that make sure new WURFL files are good when they get shipped. If you hack a local copy of WURFL, though, you have to be careful that the wurfl.xml file is not broken in subtle ways. Also, check out the patch file article.

Finally, there are many device elements in WURFL which contain the substring 'generic' in the WURFL ID. These are typically IDs which group together families of devices with common characteristics. In the first years of the WURFL project, families tended to be created around browsers (i.e. devices with the same browser would be gathered under a common family). As more capabilities not related to browsers were introduced and as mobile OSes became more relevant factors for phones (iOS, Android, Symbian^3 and so on), the shift moved to OSes, which is the logic according to which new devices are grouped today (for ex.: 'generic_android_ver2_1').
Back to top

Q: What does the 'actual_device_root' represent?
A:  WURFL models devices which only differ in the firmware subversion of the software as different devices. This is good, since it allows WURFL-based applications to handle correctly only apparently identical devices. One side effect is that certain devices are responsible for 10 or 20 WURFL entries. This would normally prevent APIs from using the WURFL to easily compile lists of devices made by unique make and model. The actual_device_root="true" attribute enables this. The API can be used to select one and only one device out of a family of firmware subversions.
Back to top

Q: How to query WURFL information.
A:  Actual device data is just a part of what the WURFL project offers you. WURFL is also about APIs to query device information. The WURFL website offers APIs for Java, PHP, DotNet (standard APIs). More platforms are supported by the ScientiaMobile WURFL Cloud.
The Standard APIs are offered with the Affero GPL (AGPL) License software license. Commercial licensing is offered by ScientiaMobile, Inc.
Back to top

Q:What is a 'patch file'?
A:  If you need to add device information to your application, managing the WURFL file directly is probably unpractical, since this would impair your ability to upgrade to future WURFL versions without overwriting your changes.
The patch file has been introduced to help with this problem. Rather then modifying the WURFL directly, you can define a patch file that looks like some kind of mini-WURFL. Once the WURFL is loaded, APIs can use a the patch file to enrich the data in the WURFL itself. From this moment new WURFL versions can be imported without overwriting local data.
A more thorough discussion of patch files can be found at:
Back to top

Q: My 'patch file' does not work. What did I get wrong?
A:  The process of patching is:
  1. Copy *exactly* the <device/> that you are patching (no subelements)
  2. Insert only the changed capabilities within the <device/>
  3. If you add a new capability, you must also patch the generic device with the default value for that capability.
For example, to patch:
<device user_agent="BlackBerry5810/3.6.0"
        fall_back="blackberry_generic_ver3_sub60" id="blackberry_5810_ver1_sub360">
   <group id="product_info">
      <capability name="model_name" value="BlackBerry 5810"/>
   <group id="display">
      <capability name="rows" value="16"/>
      <capability name="columns" value="26"/>
so that a new capability, "my_height" is available in group "display", the patch file should contain two entries:
<!-- so we register the 'default' value, and add this capability to the
list of available capabilities -->
<device user_agent="" fall_back="root" id="generic">
   <group id="display">
      <capability name="my_height" value=""/>

<!-- patch on the capability to the device mentioned above -->
<device user_agent="BlackBerry5810/3.6.0"
         fall_back="blackberry_generic_ver3_sub60" id="blackberry_5810_ver1_sub360">
   <group id="display">
      <capability name="my_height" value="150"/>

Back to top

Q: I found an error in the WURFL. What shall I do?
A:  You can follow these instructions.
Back to top

Q: Who created the WURFL?
In 2001, Luca Passani architected the file structure, the fall_back mechanism and created most capability names, based on his experience with previous frameworks he had created dealing with Device Fragmentation. He also architecting the WURFL API and the patch file.
In 2007, Luca created a company (WURFL Pro S.r.l.) that re-created the new APIs for Java, .NET and PHP from scratch. The company also created the WURFL DB and hired paid staff to keep the repository updated.
Steve Kamerman created the possibility of injecting WURFL into a RDBMS and ported the WURFL PHP API to allow using MySQL or another DB as the backend.
Luca and Steve co-founded ScientiaMobile, Inc. in 2011 to provide professional tools and support to companies which adopted WURFL. The company CEO is Krishna Guda (also a co-founder of ScientiaMobile).

Back to top

Q: How do I contribute device information to WURFL?
A public website called WURFLDB (available at db.scientiamobile.com) allows contributors to submit device info directly into WURFL. Contributors are approved by ScientiaMobile. All contributors will need to agree to assign rights about the data they submit to ScientiaMobile.
WURFL DB contributors will typically come from large mobile companies and operators. Having a handful of device information to share is not enough to be granted contributor rights.
Details about what WURFLDB is and how to become a contributor can be found at https://db.scientiamobile.com/static/become_a_contributor.htm.
Back to top

Q: Who is the WURFL maintainer?
A:  ScientiaMobile, Inc., a US company headquartered in Reston, Virginia.
Back to top

Q: Which programming APIs are available for WURFL?
A:  The WURFL Standalone APIs are available for PHP, Java and Microsoft .NET. In addition to these, an additional API, called the DB API (formerly Tera-WURFL) is also available. The DB API is essentially a PHP API that stores WURFL data into a relational database (MySQL). These APIs are released under a dual AGPL-v3/commercial licensing scheme.

A WURFL C++ API is also available commercially from ScientiaMobile.

In addition to the StandAlone APIs, ScientiaMobile offers a WURFL Cloud service with several plans and the ability to integrate it with a plethora of programming languages, such as: Java, PHP, Microsoft .NET, Ruby, Python, Node.js and Perl.
Finally, WURFL Modules for Apache, Varnish-Cache and NGINX can also be licensed commercially. These modules are based on the C++ WURFL API by ScientiaMobile.
Back to top

Q: Can WURFL be integrated with web-servers and proxies such as Apache, Varnish-Cache, NGINX?
A:  Yes, it can. ScientiaMobile has released WURFL Modules for Apache, Varnish-Cache and NGINX. This blog post by Scientiamobile has more details. The Modules are only available to commercial users, albeit ScientiaMobile is generally open to 'try-before-you-buy'.
Back to top

Q: I have a new device. How do I get it added to the WURFL?
A:  Please refer to this: http://wurfl.sourceforge.net/contribute.php.
You may also want to capture a full set of HTTP headers at: http://db.scientiamobile.com/h (there is no point in visiting this page with a Desktop web browser).
You may also want to take a look at this FAQ: How do I contribute device information to WURFL?.
Back to top

Q: Is there a simple way to browse the WURFL?
A:  One can always download and install WURFL API and repository from the SourceForge website.,br/> Casual WURFL inquiries can be found on the WURFL DB http://db.scientiamobile.com/. The WURFL DB also allows searching in the latest WURFL repository. Important: rhe WURFL DB does NOT implement any of the matching APIs and logic, so searching for a complete UA string may not return a result, in spite of the fact that the device is recognized perfectly by the WURFL API.
Please observe that screen-scaping attempts are not taken lightly by the ScientiaMobile team.
Finally, a new tool to match a USer-Agent against the latest and greatest WURFL API is available at: http://tools.scientiamobile.com (You can access this page with any kind of browser/device).
Back to top

Q: ALARM! ALARM! Device X is not in WURFL
A:  In addition to the flow of device data that ScientiaMobile manages autonomously and adds to WURFL, WURFL is open to feedback from the community. If you have a new device we have not heard of, check this page http://wurfl.sourceforge.net/contribute.php for information about how to get it added to the WURFL.
You may also want to take a look at this FAQ: How do I contribute device information to WURFL?.
Back to top

Q: Is there a WURFL mailing list?
A:  Sure thing! It's called WMLProgramming on Yahoo Groups.
Back to top

Q: Is there a WURFL book?
A:  While there is no book specifically on WURFL alone, pretty much every mobile web development book published from 2006 and on mentions WURFL more or less extensively. In particular, you can look at the following books:
Back to top

Q: What is UAProf?
A:  UAProf (User Agent Profile) is a standard created by OMA to describes the capabilities of a device/browser. This information is in the form of an XML document and usually covers the following device attributes:
  • Hardware Platform, eg screen size, audio capability colour capability.
  • Software Platform, eg operating system, content types etc.
  • Network Characteristics; eg GSM/GPRS capable, WLTS capable etcBrowser;
  • Browser name and version, xHTML version, JavaScript Support
  • WAP Characteristics; WML version, deck size, OMA download
  • Push Characteristics; Push content types, application.
This is similar to what WURFL offers. In fact, UAProf is some kind of industry standard to represent device capabilities. Since it is not feasible for a device to send this information over the air with each request, the profiles are stored in (normally) publicly accessible repositories so that all a device needs to do is to state the URL of its UAProf. Theoretically, applications should be able to retrieve this profile programmatically (give and take some caching) and dynamically repurpose the content for the each device. Of course, always theoretically, you don't need the WURFL.
In practice, you really need the WURFL, because:
  • UAProf profiles are often wrong
  • Old devices do not have UAProf
  • UAProf is hosted at non-public URLs (only apps in the domain of a given operator have access to them)
  • Even if you fix UAProf, you may not be legally allowed to re-host it at a different URL
  • There's no free or cheap middleware to use UAProf out of the box
  • Apple, Google and Microsoft decided to ignore UAProf. iPhones, iPads, most Android devices and most devices with Microsoft mobile OSes do not send a UAProf URL in their headers

Back to top

Q: How does UAProf releate to WURFL?
A:  When a new device hits the market, the UAProf data (if available for that device) is used to populate WURFL. Of course, if the community finds that some of the data is wrong, the data gets fixed for everyone's enjoyment. In other words, WURFL offers one level of indirection which goes a long way in making WURFL more valuable than UAProf for developers.
It may also be fair to describe WURFL as "UAProf the way it should have been done if people in standard bodies had a clue".
Back to top


Q: Is there a quick way to check what value WURFL returns for a given user-agent string?
A:  The form available on this site's home page and the ScientiaMobile home page will reveal what the latest and greatest (commercial) WURFL thinks of the user-agent string provided with the form.
Local installations may return different results either because the API run by ScientiaMobile has not been released or (more likely) because the public snapshot of WURFL is older than the commercially available WURFL.
Back to top

Q: UA string blackberry8100/4.2.0 profile/midp-2.0 configuration/cldc-1.1 vendorid/125 is not matching. How is that possible?
A:  In this particular case, that UA string is not matching because it is not the UA string sent originally by the device. The device actually sent this: BlackBerry8100/4.2.0 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/125 (i.e. someone or something removed capitalization).
In general, capitalization matters when it comes to UA strings and care should be taken by whoever is managing UA strings at any level to preserve them in their original form. Even the slightest manipulation may make them useless.
Back to top
Back to top

Q: I have a question about WURFL [Device Data|Repository|API|Licensing], where can I get support?
A:  ScientiaMobile hosts a WURFL support forum that is constantly attended by ScientiaMobile's support staff. Users need register with the site in order to be able to post questions, but there is no requirement to be a commercial licensee (of course, everyone is expected to use WURFL according to the license with which they obtained the software and or their copy of the repository).

In addition to this, there is a mailing list called WMLProgramming at Yahoo groups, which is attended by ScientiaMobile personnel (notably, Luca Passani, WURFL Inventor and ScientiaMobile CTO, and Steve Kamerman, creator of the WURFL DB API). ScientiaMobile's WURFL support forum is still preferrable (others will be able to access answers at a later stage).
Back to top

WURFL Licensing

Q: What is the license for WURFL?
A:  This is actually two separate questions. First, What's the license for the WURFL Repository? and secondly, What's the license for the WURFL APIs?.

You can also look at this page
Back to top

Q:What's the license for the WURFL Repository?
A:  The repository is managed by ScientiaMobile, which collects and organizes public device information, as well as contributions by third-parties (developers, device manufacturers, organizations that provide raw device access data).
ScientiaMobile owns the copyright for the WURFL dataset and its structure, and it only allows users to use the data in connection with one of the standard WURFL APIs released and supported by ScientiaMobile.
WURFL users are not allowed to use, copy, display and distribute derivative work of the WURFL data.
Organizations who intend to use the WURFL repository commercially should contact ScientiaMobile about licensing options.
Additional license options, as well as more frequent updates of the wurfl.xml file, are available to commercial licensees of the WURFL framework.

ScientiaMobile's FAQ provides more information about WURFL commercial licensing options and advantages.

Back to top

Q: What's the license for the WURFL APIs?
A:  The WURFL standard APIs (the ones provided by ScientiaMobile) are offered according to a dual licensing scheme.
The FOSS license applicable to the APIs when the APIs are downloaded from SourceForge is the Affero GPL (AGPL) License, version 3. Companies that are not comfortable with AGPL, can acquire a commercial license for use of the software from ScientiaMobile, Inc..
Third-party non-standard APIs come with licenses from the respective copyright holders.
Back to top

Q: Why is AGPL not good enough for commercial software?
A:  From a purely theoretical viewpoint, there is no incompatibility between AGPL and commercial applications. One may be running a commercial service while making the source code open and available to third-parties. Of course, things are likely different in practice. AGPL employs so-called 'strong copyleft', i.e. the demand that all the software linked against free software (free in GNU/FSF sense of the term) is also free software and openly available to everyone. GNU Public License is the most famous of such 'strong copyleft' FOSS licenses. The GPL copyleft clause triggers when an application is distributed outside of company boundaries. The GPL license was created at a time when the web did not exist, let alone the possibility to use applications remotely through a web browser. Because of this, companies could deploy GPL code commercially on a web server without betraying the letter, but arguably betraying the spirit, of the GPL. This is called the ASP loophole. This is the context in which Affero was designed. The basic idea is that making AGPL software available through a web server constitutes distribution, and this is enough to trigger the strong copyleft provisions that many are already familiar with because of GPL. In other words, all of the software that links to the AGPL library must also be released with a compatible Free or Open-Source license.
Commercial companies are unlikely to want to have to disclose and distribute the source code with which they use WURFL. If that is the case, ScientiaMobile offers the same APIs commercially under a license that will not require the company to disclose the source code with which it uses WURFL. This is called selling/buying a GPL exception in GNU parlance, even though the expression 'dual licensing' is normally used in everyday speech.
Back to top

Q: If I use the AGPL API, will I need to open-source my code even if I don't modify the API?
A:  Yes, you will. Exactly like regular GPL, linking your code to GPL code creates derivative work (in the copyright sense of the term) and this is enough to trigger the 'copyleft' provisions. FSF is adamant on this interpretation and so is ScientiaMobile.
Back to top

Q: What's the price of a commercial API license from ScientiaMobile?
A:  This kind of questions are better asked to ScientiaMobile directly through their API License Inquiry form. General information is also provided in the Product Page.

ScientiaMobile once informally explained the license structure as follows:

"ScientiaMobile licensing is based on the 'tip-the-barman' concept, i.e. having access to an open bar at a party is cool, but in order to keep the party going, guests should tip the barman. Even when considering the tip, an open bar is still a lot cheaper than a regular bar. Similarly, WURFL Commercial licensing is still a lot cheaper than commercial solutions in the same space. ScientiaMobile's license fees are simple flat license fees and, for example, exclude complicated license fee multipliers such as the concept of charging based on the number of CPUs.
Open-bar analogies aside, the ScientiaMobile commercial licensing is based on the concept that each company that uses WURFL commercially will need to pay something for it. This will contribute to more better WURFL for everyone.
If a company is using the API for its own company mobile website exclusively, they'll probably just need to pay a reasonable, small fee to acquire a single license.
OEM licensing is for companies that are involved with running other companies' sites, and can be acquired on bulk-discount rates. Let me provide a few different scenarios as examples: a company may have a CMS solution that uses WURFL as a DDR to serve the sites of multiple companies. In that case, the CMS vendor should get an OEM license. An OEM license would also be appropriate for software vendors who intend to bundle the WURFL API with their own software. In the two cases I just described, the pricing will change based on the number of «authorized users» to whom the licensee wants to offer the right to use the API. The OEM license is priced according to how many third-party companies will use the software. Of course, with the OEM license, volume means a way cheaper average price for each authorized-user seat. Some of our OEM customers are using this to their advantage by advertising that their mobile solutions include the usage of a legitimate WURFL API worth the value of a single API.
Of course, we do not allow anyone to re-license our API to third parties. A licensee can only have 'authorized-users'."

Back to top

Q: How do I know whether I need a Single License or an OEM License for my site/service?
A:  You will need to ask ScientiaMobile directly to be sure. One of the commercial guys from ScientiaMobile provided the following rule-of-thumb:

"If all you need WURFL for is a simple company mobile site that only offers non-mobile services to end-users, then the Single license is probably enough. The same probably applies if you need WURFL for a single company's reporting/analytics purposes. On the other hand, if your company is providing mobile services, the key question you should ask yourself is: 'Do customers of my WURFL-based service still need to acquire their own copy of WURFL to operate their own mobile site?'. If the answer is yes (i.e. your customers will still need to buy a DDR and that DDR might be WURFL) then a Single license is probably enough for you.
On the other hand, If the answer is no and your application removes the need for your customer to acquire WURFL or another DDR, then you probably need to acquire an OEM license with enough authorised-user seats to serve all of your customers.
For example, a CMS service that lets customers build mobile websites would obviously remove the need for those customers to obtain a separate WURFL license. In that case, the CMS vendor will need to acquire an OEM license with enough 'authorized user' seats to cover all its customers that will be using WURFL in some way."

Back to top

Q: I run an Ad Network and I need WURFL to target my ads. Will I need a Single or an OEM License?
A:  "ScientiaMobile offers an Ad Network license specifically for usage by Ad Networks."
Back to top

Q: If I acquire a Single and OEM Commercial API license today, when and how much will I need to pay next?
A:  Licences will typically need to be required yearly. Something called a 'perpetual license' exists, but that was introduced to prevent lock-in for companies that need to deal with varying budget costraints every year and do not want to lose the right to use the software from one day to the next. A perpetual license assigns perpetual rights on the code, meaning that if you acquire license for code X.Y, that code is licensed to you for the rest of time. What you are NOT getting perpetually is the right to license newer versions of the API. If ScientiaMobile releases version X.Z within one year from when you acquired your API license, you are entitled to a license for the new version.
After one year, ScientiaMobile's customers will need to buy a new NVC (New Version Coverage) to license newer versions of the API (and maintaning the access to weekly repository updates).
Licensees of am expired perpetual license can still use the public WURFL snapshot, but they are not allowed to upgrade to a newer API.
Back to top

Q: I created my own API. Should I pay for the license?
A:  Probably yes. From a technology perspective, the WURFL repository is tightly coupled to the standard WURFL APIs released by ScientiaMobile, so a non standard API may be performing sub-optimally without you realizing.
To add to that, the public releases of the WURFL repository comes with a license that prohibits usage of the public repository with third-party APIs, while the commercially licensed repository does not have this limitation.
Finally, many of the non-standard APIs simply copied large amounts of code (notably the matchers) from the standard API, so they are derivative work of the standard API and as such open to questiona about IP ownership and compliance to AGPL.
Back to top

Q: I would really like to pay for my company's use of the WURFL API, but all the licensing models ScientiaMobile advertises mean excessively steep charges for my case.
A:  The nice folk at ScientiaMobile are always available to hear about companies issues with the licensing and, within reason, work with them on a pricing model that fits their needs.
You can either use the ScientiaMobile API License Inquiry form or just contact them via email: sales at scientiamobile dot com.
Back to top

Q: I purchased a license for the WURFL API {Java|PHP|.NET|Database|} edition, but we also need a license for the {Java|PHP|.NET|Database|} edition in my company. Do I need to pay more..
A:  Yes, you do. The good news is that you can buy a single license for all the platforms cheaper than the sum of all license prices. Existing customers in similar situations were able to get substatial discounts on the price of an extra single license after contacting sales at ScentiaMobile.
Back to top

Q: How often are public snapshots of the WURFL repository released?
A:  ScientiaMobile's answer:

"We release public snapshots of the WURFL DB about once every quarter. This is frequently enough for most non-commercial uses.
If a company feels the need to have more frequent updates, they should seriously consider acquiring a commercial WURFL license. This will mean access to a personal customer vault with weekly updates of the WURFL DB."

Back to top

WURFL and Java

Q: The default level of debugging is info. How can I change it to debug?
A:  Two changes are needed:
  1. Edit the boolean variable IS_DEBUG_ENABLED defined in the class WURFLConstants.java: default value is false, so, in order to enable debugging, you should set it as true.
  2. Edit the logback.xml file of your application in order to set as debug the level of debugging of the package(s) of interest:
<logger name="com.scientiamobile.example" level="info" />
<logger name="net.sourceforge.wurfl.core.resource" level="info" />
<logger name="net.sourceforge.wurfl.core.handlers" level="info" />

Back to top

Q: The default caching strategy is DoubleLRUMapCacheProvider. How can I change it?
A:  You can find an example in the wurfl-custom-ctx.xml configuration file provided with the wurfl-helloworld-spring-1.4.x Web Application example. Firstly, you have to specify that the application has to use the wurfl-custom-ctx.xml file instead of the default one (wurfl-ctx.xml), by editing the web.xml file of your Web Application:
Then, you can define the custom caching strategy by adding the cacheProvider property setting to the GeneralWURFLEngine bean definition, contained in the wurfl-custom-ctx.xml file:
	<bean id="WurflHolder" class="net.sourceforge.wurfl.core.GeneralWURFLEngine">
		<constructor-arg index="0" value="classpath:/wurfl.zip" />
		<!-- <constructor-arg index="1" value="<< patch here >>"/> -->
		<!-- <constructor-arg index="2" value="<< more patches here >>"/> -->
		<property name="cacheProvider" ref="deviceCacheProvider" />
Finally, in the same file, you add the deviceCacheProvider description, where you can set the specific class (implementing the CacheProvider interface) that you want to use. The class can be custom or one of the provided ones (LRUMapCacheProvider, EhCacheProvider, HashMapCacheProvider, etc.):
      <bean id="deviceCacheProvider" class="net.sourceforge.wurfl.core.cache.LRUMapCacheProvider" />

Back to top

Q: How can I set a custom CapabilitiesHolderFactory class to be used?
A:  Similarly to the previous case, you firstly have to set wurfl-custom-ctx.xml as the context configuration file to be used (by editing the web.xml file). Then, you can define the custom caching strategy by adding the cacheProvider property setting to the GeneralWURFLEngine bean definition, contained in the wurfl-custom-ctx.xml file:
	<bean id="WurflHolder" class="net.sourceforge.wurfl.core.GeneralWURFLEngine">
		<constructor-arg index="0" value="classpath:/wurfl.zip" />
		<!-- <constructor-arg index="1" value="<< patch here >>"/> -->
		<!-- <constructor-arg index="2" value="<< more patches here >>"/> -->
		<property name="capabilitiesHolderFactory" ref="capabilitiesHolderFactory" />
Finally, in the same file, you add the capabilitiesHolderFactory description, where you can set the specific class (implementing the CapabilitiesHolderFactory interface) that you want to use:
	<bean id="capabilitiesHolderFactory" class="net.sourceforge.wurfl.core.DefaultCapabilitiesHolderFactory" />

Back to top

Back to top

Q: How do I switch between High-Performance (HP) and High-Accuracy (HA) mode?
A:  To configure WURFL API to run in High-Performance or High-Accuracy mode, you can edit the XML /META-INF/wurfl-config.xml configuration file (the Java API refers to this at engine-target).

for High-Accuracy mode:
 <wurfl-api-config engine-target="accuracy">
for High-Performance mode:
 <wurfl-api-config engine-target="performance">
High-Performance is the default target.
Back to top

Q: What's the Introspector and how do I deploy it?
A:  The Introspector is a servlet ready to be deployed on your server, that lets you query the library remotely for profiling and debugging purposes. A common way to declare the Introspector servlet on your server is to add the following XML portion to your web.xml configuration file:
    <!-- introspector servlet -->

    <!-- mapping -->
You can find an example of how to initialize and query the Introspector in the wurfl-introspector- web application (see Java Download area).
Back to top

Q: Is there a way to loop on all the devices in WURFL with the Java API?
A:  Yes, there is. Here you go:
package wurfl;

import java.util.Set;
import com.scientiamobile.reloader.DefaultReloadableWURFLEngine;
import com.scientiamobile.reloader.ReloadableWURFLEngine;
import net.sourceforge.wurfl.core.Device;
import net.sourceforge.wurfl.core.WURFLUtils;

public class LoopAllDevices {

	public static void main(String[] args) {
		ReloadableWURFLEngine wurfl = new DefaultReloadableWURFLEngine("wurfl-data/wurfl.zip", null);
		WURFLUtils utils = wurfl.getWURFLUtils();
		Set<String> ids = utils.getAllDevicesId();
		System.out.println("Printing all Devices ID...");

		int i = 0;
		for (String str:ids) {
			System.out.println("Device #" + i + ":");
			// get the actual device:
			Device device = utils.getDeviceById(str);
			// get the device root:
			String rootDevice = device.getDeviceRootId();
			System.out.println("Root device is: " + rootDevice + "\n");

Back to top

Q: I cannot specify a relative path to the wurfl.zip file (for ex. WEB-INF/wurfl.zip). What am I doing wrong?

A:  This was a bug fixed in version of the Java API. In the process of simplifying the API and its dependencies, we removed dedicated holders, including ServletContextWURFLHolder, which was the class capable of managing relative paths.

With version of the WURFL API, you can configure your web.xml file as follows:

Back to top

Q: Can a new wurfl.xml file be reloaded without restarting my Java application (Hotswap)?

A:  The WURFL Java provides engine implementations to reload the wurfl.xml(.zip/.gz) file at runtime.
During the XML data acquisition, the incoming requests are queued, and then the matching process is resumed at the end of the XML data reloading process.
Apart from the short delay (order of couple of seconds), this process is completely transparent to the rest of the application.
The key method is called "reload", and comes with different signatures in the WURFLEngine interface.
You can use it to instantiate the running WURFL instance in your application, and call the reload() method to reload the wurfl.xml (and patches, if present) at runtime.

Q: Is there a Maven repository for WURFL?

A: A Maven repository is available for commercial license holders (read more here). General Maven support was removed in 2011 in order to prevent injecting AGPL code into your builds without knowledge of doing so.

Back to top


Q: What's required to make WURFL work under ASP.NET Web Forms and ASP.NET MVC?
A:  WURFL 1.4 for .NET requires at least the .NET Framework 2.0 and works on both flavors of ASP.NET in the same way. The instructions you find in the documentation to start WURFL on ASP.NET work regardless of the type of ASP.NET framework you're using.
WURFL 1.4 for .NET comes with two distinct assembliesócore WURFL engine (named wurfl) and an ASP.NET specific assembly (named wurfl.aspnet.extensions). The ASP.NET specific assembly contains optional classes such as a few extension methods on the HttpRequest class to create a WURFL request from an HTTP context request. In addition, the ASP.NET specific assembly contains classes for web.config based configuration.
Back to top

Q: How does the Introspector work for ASP.NET?
A:  The WURFL Introspector for ASP.NET is an HTTP handler hard-coded in the library and specifically in wurfl.aspnet.extensions assembly. It serves the purpose of querying the library remotely for profiling and debugging purposes. You can explicitly enable the introspector by placing the introspector.ashx file in a public location of your site.
Back to top

Q: Missing classes in WURFL 1.4 for .NET
A:  WURFL 1.4 for .NET hides several classes that were publicly exposed in earlier versions of the library. This is simply the result of some housekeeping and doesn't affect in any way the functionality and/or the performance. Most of the same classes work in the same way but are not publicly manageable by developers. If you want to put your hands on these classes, however, you grab the source code and play with it. Overall, the public interface of the WURFL 1.4 API for .NET passes through the IWURFLManager interface. You get an instance of an object that implements this interface through the WURFLManagerBuilder public class. That's all of it.
Back to top

Q: How to switch between High-Performance (HP) and High-Accuracy (HA) mode (WURFL .NET API 1.4)
A:  The match mode is an additional parameter you can use to instruct the WURFL API 1.4 on how to detect a device. By default the WURFL API works in High-Performance mode but in .NET this setting can be changed for the entire application as well as for individual requests. You set the match mode through the configurer object of choice. If you use the InMemoryConfigurer, you can pick a match mode with the following method:
 public InMemoryConfigurer SetTarget(MatchMode target)
The MatchMode type is an enumerated type with two possible values: Performance and Accuracy. If you use the ApplicationConfigurer to set up your WURFL application, then you use the new mode XML attribute on the <wurfl> node. You set the mode attribute to either Accuracy or Performance.
<wurfl mode="Performance|Accuracy">
    <mainFile path="~/App_Data/wurfl.zip" />
The mode attribute is optional; if not specified it defaults to Performance. Finally, you can also set the match mode on a per-request basis. In this case, the match mode you indicate works only for the specific request. Successive requests will default to whatever option you set through the configurer object. You indicate the match mode for a request using one of the overloads for the GetDeviceForRequest method as below:
 var deviceInfo = GetDeviceForRequest(userAgent, MatchMode.Accuracy);
Note also that a request that indicates explicitly a match mode will not be served through the internal cache and will not have the response cached for further references.
Back to top

Q: Is there a way to loop on all the devices in WURFL with the .NET API?
A:  To gain access to all devices referenced in the WURFL database, you use the method GetAllDevices defined on IWURFLManager interface. Note that this method requires version 1.4.1 of the .NET API.
 var configurer = new ApplicationConfigurer();
var wurflManager = WURFLManagerBuilder.Build(configurer);
var devices = wurflManager.GetAllDevices();
The devices variable is a collection that contains a few thousands of IDevice objects. You can loop over the content of the devices variable using a for-each statements, as shown below:
foreach(var device in devices)
    // ...
To grab details about a particular device you use the members of the IDevice interface.
Back to top


Q: What are the minimum requirements for PHP to use the API ?
A:  PHP 5.1+
Back to top

Q: I am getting this error: parse error, unexpected T_CONST, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' ?
A:  Make sure you are using PHP 5.1+
Back to top

Q: I can use wurfl.xml but I am having problems with wurfl.zip
A:  Make sure you have the PHP Zip extension installed and enabled. It is installed by default on PHP 5.2.0+.
Back to top

Q: What is the difference between Cache and Persistence?
A:  The Persistence provider is used by the API to store all the devices from the WURFL File, whereas the Cache provider is used to store only the requested devices at runtime. In version 1.4.0, if you use the APC or Memcache Cache provider, they will also be used as a caching layer on top of the Persistence provider, so, for example, if you are using File for Persistence and APC for Cache, calls to the Persistence layer will first check APC, then the Filesystem.
Back to top

Q: Why should I enable caching?
A:  For performance - the default setup uses the Filesystem for Persistence and Caching. The WURFL API will make at least four calls to the Persistence provider every time the API is loaded, so using a Cache provider like APC will reduce this to zero calls to the file system and four calls to APC which are virtually instantaneous.
Back to top

Q: I changed the wurfl.xml or added patch files, but i can't see any difference.
A:  The WURFL File must be reloaded after you make any changes. The easiest way to force a reload is to clear your Persistence and Cache providers (ex: delete the contents of the storage/persistence and storage/cache folders and restart Apache for APC or the memcached service for Memcache)
Back to top

Q: The API is not working with APC or Memcache
A:  Make sure you have installed and enabled the corresponding PHP extensions: apc or memcache
Back to top

Q: Which class/method should I use from the WURFL API to detect between a mobile request and or a desktop PC request.
A:  Capability is_wireless_device is your friend:
   if ( is_wireless_device == 'true' ) {
   	the request is from web browser

Cloud users and commercial WURFL users also have access to a capability called ux_full_desktop which will indicate Desktop Web Browsers, while making sure that SmartTV and other non-Desktop HTTP clients are excluded.

Back to top

Q: How do I switch between High-Performance (HP) and High-Accuracy (HA) mode?
The WURFL APIs ship in High Performance mode by default. If you are using the default configuration from version 1.4+, you can use the matchMode() method on your configuration object:

// Use High Accuracy Mode
   // --- OR --- //
// Use High Performance Mode

If you are using the XML configuration method, you can set the mode using the <match-mode> element:


	<!-- High Accuracy Mode -->
	   <!-- OR -->
	<!-- High Performance Mode -->


Back to top

Q: What is the Introspector and how do I set it up in the PHP API?
The Introspector is used for profiling and debugging a running installation of the WURFL API. To use it, you must update examples/Introspector.php with your API configuration, then you can visit it in your browser to test user agents and see information about your installation and platform.

Back to top

WURFL and PHP - Database API (formerly Tera-WURFL)

Q: What are the minimum requirements for the Database API?
A:  PHP 5.1+
Back to top

Q: What are the different database connectors and how do I use them?
A:  There are five main database connectors: MySQL4, MySQL5, PDO, MongoDB and MSSQL2005.

  • MySQL4 Used for MySQL 4 or 5. Requires the mysqli extension. This connector is similar to the MySQL5 connector, except it does not use MySQL stored procedures. This is helpful for web hosts that use MySQL 4 or do not allow the use of stored procedures.
  • MySQL5 This is the default connector. Requires the mysqli extension. This connector uses stored procedures to decrease traffic between the web server and the database server. To specify the TCP port, put it after the hostname, seperated by a colon. You can use a UNIX domain socket connection as follows:
    public static $DB_HOST = "localhost:/var/run/mysqld/mysqld.sock";
    There is also a variant called MySQL5_NestedSet that uses a nested set model to increase the performance of device fall back iteration.
  • PDO The PDO connector is also targeted for MySQL5 servers, and requires the pdo-mysql extension. The performance of this connector is approximately the same as the MySQL5 connector, and was developed for compatibility with the high performance PHP to C++ transformer, HipHop for PHP. The connector is stable and is used extensively by ScientiaMobile. Unlike the standard MySQL connectors, the PDO connector uses a DSN connection string. The connection string is set in the DB_HOST field, and looks something like this:
    public static $DB_HOST = "mysql:dbname=tera_wurfl_demo;host=";
    See the PHP PDO MySQL DSN documentation for more details.
  • MongoDB Allows the use of MongoDB as the WURFL database. Requires the Mongo extension. This connector uses server-side Javascript (MongoCode) to improve performance of device lookups. Like the PDO connector, a connection string is required, and is set in the DB_HOST field. See the PHP MongoDB connection documentation for more information. Examples:
    // Using a TCP connection         
    public static $DB_HOST = "mongodb://localhost:27017";
    // Using a UNIX domain socket connection
    public static $DB_HOST = "mongodb:///tmp/mongodb-27017.sock";
  • MSSQL2005 Provides a connection to Microsoft SQL Server version 2005 and newer. Requires the Microsoft Drivers for PHP for SQL Server. The database server and instance are specified in the DB_HOST field:
    public static $DB_HOST = "MYHOSTNAME\SQLEXPRESS";

Back to top

Q: How do I switch between High-Performance (HP) and High-Accuracy (HA) mode?
A: The Database API has inherited this feature from its Tera-WURFL days, when it was called SimpleDesktop. In order to ensure compatibility, the configuration setting is named SIMPLE_DESKTOP_ENGINE_ENABLE. In High-Performance mode (default), desktop web browser detection is done programmatically without referencing the WURFL data; as a result, most desktop web browsers are returned as generic_web_browser. Configuration example:

// High-Performance Mode
public static $SIMPLE_DESKTOP_ENGINE_ENABLE = true;
// High-Accuracy Mode
public static $SIMPLE_DESKTOP_ENGINE_ENABLE = false;
Back to top

Q: What is the Introspector and how do I set it up in the Database API?
A:  The Introspector is a tool used for profiling and debugging the WURFL API remotely. In the Database API, it is already setup and configured for use. To use it, you can visit /test/Introspector.php in your web browser.
Back to top

Q: I am getting this error: Error in DB RIS Query: PROCEDURE TeraWurfl_RIS does not exist

Error in DB RIS Query: PROCEDURE TeraWurfl_RIS does not exist
Fatal error: Uncaught exception 'Exception' with message 'Error in DB RIS Query: PROCEDURE TeraWurfl_RIS does not exist. 
Query: CALL TeraWurfl_RIS('SonyEricssonK700i/R2AC SEMC-Browser/4.0.2 Profile/MIDP-2.0 Configuration/CLDC-1.1',16,'SonyEricsson') ' in /var/www/html//Tera-Wurfl/DatabaseConnectors/TeraWurflDatabase_MySQL5.php:103
Stack trace: 
#0 /var/www/html/Tera-Wurfl/UserAgentMatchers/UserAgentMatcher.php(63): TeraWurflDatabase_MySQL5->getDeviceFromUA_RIS('SonyEricssonK70...', 16, Object(SonyEricssonUserAgentMatcher)) 
#1 /var/www/html/Tera-Wurfl/UserAgentMatchers/SonyEricssonUserAgentMatcher.php(30): UserAgentMatcher->risMatch('SonyEricssonK70...', 16) 
#2 /var/www/html/Tera-Wurfl/TeraWurfl.php(96): SonyEricssonUserAgentMatcher->applyConclusiveMatch('SonyEricssonK70...') 
#3 /var/www/html/Tera-Wurfl/TeraWurfl.php(202) in /var/www/html/Tera-Wurfl/DatabaseConnectors/TeraWurflDatabase_MySQL5.php on line 103
A: This error indicates that the TeraWurfl_RIS stored procedure did not get properly created in the MySQL Database. This procedure is dropped and created every time the database is loaded. There are only four reasons for you to get this message:
  • You have never updated your database from the Web Administration Page.
  • Your database user (specified in TeraWurflConfig.php) does not have the required permissions in MySQL.
  • Your TABLE_PREFIX in TeraWurflConfig.php is empty. This prevents the creation of the stored procedure.
  • Your database server or web host does not support stored procedures - you'll need to use the MySQL4 connector.
  • Back to top

    WURFL Cloud

    Q: What is the WURFL Cloud?
    A: The WURFL Cloud Service is a highly-available installation of the WURFL Device Description Repository that allows companies to query updated mobile device information in real time. Regular APIs require that developers or system administrators periodically download and deploy a newer wurfl.xml file, to enrich the DDR with the device profiles of recently-released devices. The Cloud makes this unnecessary thanks to a light-weight API that has access to constantly updated repository and API through the Cloud. The Cloud product is comprised of essentially two parts:

    The WURFL Cloud Client: this is a library which can analyze an HTTP request and create a corresponding query to the WURFL Cloud Server over HTTP. The Cloud client is effectively a WURFL API and it is available in PHP, Java, .Net, Ruby, Perl, Python and Node.js. A strategy for local caching is usually adopted to minimize latency. A monthly WURFL Cloud Service subscription is required to obtain the credentials to query the WURFL Server.

    The WURFL Cloud Service: this is the highly-available service managed by ScientiaMobile. Subscribers are given access to a Cloud Control panel from which they can (among other things) download the cloud clients for the different languages, find their unique key to use the service and access a report about their usage.
    Back to top

    Q: Who can use the WURFL Cloud?
    A: WURFL Cloud is open to companies of all sizes, though no OEM clients or software as a service companies (SaaS) can use the WURFL Cloud client to resell WURFL to their customers. You should refer to the Terms and Conditions for the use of the service if in doubt.
    Back to top

    Q: I am a hobbyist. Can I still use ScientiaMobile's WURFL Cloud?
    A: ScientiaMobile also offers the Cloud free of charge to micro-companies, hobbyists and companies that simply want to evaluate the Cloud. Free usage is limited to 2 capabilities and 5000 device detections per month.
    Back to top

    Q: What counts as a detection?
    A: A detection in the WURFL Cloud product is counted as a unique visitor in a 24 hour period. The number of detections you need will be roughly equal to your unique visitors in a given month.
    Back to top

    Q: How can I get more capabilities and/or detections?
    A: Extra capabilities can be added to the basic and standard plans for a $5/month charge. To get extra detections, you will need to upgrade to the next plan level. If you are still hitting detection barriers, please contact ScientiaMobile for a custom solution.
    Back to top

    Q: Which languages are supported for talking to the WURFL Cloud?
    A: Here is a list of languages for which a WURFL Cloud API exists: PHP 5.1+, Java 1.5+, ASP.NET 2.0 through 4.0, Perl, Node.js, Ruby and Python are officially supported. In addition to this, at least one premium customer has been allowed to 'speak JSON' to the Cloud directly.
    Back to top

    Q: Is the Cloud Client the same for free, basic, standard and premium offers?
    A: The free, basic and standard offers share the same cloud client (simple cloud client). The premium offer requires a different cloud client (premium cloud client).
    The main difference between the two clients (simple vs. premium) is the persistence layer (AKA caching layer) that the premium Cloud Client introduces to sustain large amounts of traffic. The simple client will rely on the device cookies.
    Back to top

    Q: I am testing the Cloud with FireFox/Chrome/Opera and plug-in X/Y/Z to spoof the user agent. I always get the same (wrong) results back from the cloud. Am I missing something?
    A: Yes. You are missing the fact that the Cloud Client will rely on cookies to store capabilities and avoid extra roundtrips to the Cloud for devices that were previously serviced. If you want to use a desktop web browser (or other tool that spoofs the UA string) for testing, you should make sure that cookies are disabled or cleared. This is explained in the WURFL Cloud getting started guide.

    "...By default, the WURFL Cloud uses client-side cookies to cache device information in the browser. As a result you will need to temporarily disable cookies in your desktop web browser to test for different devices. The method to disable cookies varies from browser to browser. Below are instructions for Firefox. For other browsers, please refer to your browsers documentation..."

    Q: What will happen if I exceed my allowed number of detections?
    A: The WURFL Cloud Client will throw an exception, such as WurflCloud_Client_AuthException for PHP (and similarly for other languages) if you have exceeded your detections. You can use a try {}/catch {} block to keep the exception from bubbling up to your application.
    Apart from that, the service will keep working for a period that is long enough to assume that you have received notifications that the limit is exceeded and you should upgrade your account. Of course, if no action is taken, the Cloud will eventually refuse service until the next billing period.