Near Field Communication (NFC) is an international standard (ISO/IEC 18092) that specifies an interface and protocol for simple wireless interconnection of closely coupled devices operating at 13.56 MHz. (see http://www.nfc-forum.org/specs/spec_list/). There are three groups of application scenarios for NFC: NFC enables wireless communication between two devices at close proximity, usually less than a few centimeters.

The NFC Working Group was chartered to produce a specification that "will be designed to permit execution in the Web browser context, and otherwise to conform to the execution and security model defined by the System Applications Working Group." Specifically, the API that was worked on in the NFC Working Group did not adhere to the Web's security model. This Note contains the final Editor's Draft reflecting this direction, the 20 October 2014 Editor's Draft. The NFC Working Group Charter expired shortly after on 1 November 2014. To more clearly communicate the scope of this specification, it is herein referred to as the "Low-level Web NFC API for Trusted Applications".

Introduction

The NFC API supports the following features:

Here are some possible use cases:

An example of use is provided below:

    var hello = new NDEFRecordText("hello world", "en-US", "UTF-8");
    
    navigator.nfc.ontagfound = function(e) {
        window.console.log('NFC Tag found!');
        var tag = e.tag;
        tag.writeNDEF(new NDEFMessage([hello]));
    }
    
    navigator.nfc.startPoll().catch(
      function(e) {
        window.console.error(e);
      });
  

This specification defines conformance criteria that apply to a single product: the user agent that implements the interfaces that it contains.

Implementations that use ECMAScript to implement the APIs defined in this specification MUST implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [[!WEBIDL]], as this specification uses that specification and terminology.

Terminology

The EventHandler interface represents a callback used for event handlers as defined in [[!HTML5]].

The concepts queue a task and fire a simple event are defined in [[!HTML5]].

The terms event handler and event handler event types are defined in [[!HTML5]].

The Event interface and the Promise interface as well as the concept of a resolver are defined in [[!DOM4]].

A NFC tag is a passive, unpowered NFC device. The NFC tag is powered by magnetic induction when an active NFC device is in close vicinity. A NFC tag contains a single NDEF message.

A NDEF message encapsulates one or more application-defined NDEF records. NDEF stands for NFC Forum Data Exchange Format, a lightweight binary message format. NDEF messages can be stored on a NFC tag or exchanged between NFC-enabled devices.

A NDEF record has a maximum payload of 2^32-1 bytes. The record also contains information about the payload size, type, and an optional identifier.

Extensions to Navigator object

The NFCManager interface is exposed on [[!HTML]]'s Navigator object.

readonly attribute NFCManager nfc
The object that exposes the default NFC manager on the device.

NFCManager Interface

The NFCManager interface defines access to NFC functionality and offers methods to control local NFC behavior like polling for targets.

Promise startPoll()
Start polling for NFC tags or peer devices, and power on the NFC hardware if needed. This method returns a new Promise to notify the caller that the NFC hardware is now polling. The resulting promise is fulfilled even if the device was already polling, as state changes are tracked with the onpollstart and onpollstop handlers.
Promise stopPoll()
Stop polling for NFC tags or peer devices. This method returns a new Promise to notify the caller that the NFC hardware stopped polling. This method may power off the NFC hardware, depending on the underlying implementation.
attribute EventHandler onpollstart
Event handler called when the pollstart event is dispatched.
attribute EventHandler onpollstop
Event handler called when the pollstop event is dispatched.
attribute EventHandler ontagfound
The tagfound event of type NFCTagEvent MUST be fired whenever a new NFCTag is detected by the NFC manager. The tag property of the event MUST contain the corresponding NFCTag object.
attribute EventHandler ontaglost
Event handler called when the taglost event is dispatched.
attribute EventHandler onpeerfound
The peerfound event of type NFCPeerEvent MUST be fired whenever a new NFCPeer is detected by the NFC manager. The peer property of the event MUST contain the corresponding NFCPeer object.
attribute EventHandler onpeerlost
Event handler called when the peerlost event is dispatched.

Event handlers

The following are the event handlers (and their corresponding event handler types) that MUST be supported as attributes by the NFC object.

event handler event name event type short description
onpollstart pollstart simple event fired when the polling state changes to true
onpollstop pollstop simple event fired when the polling state changes to false
ontagfound tagfound NFCTagEvent with tag property set to the new NFCTag object. detect a new NFCTag
ontaglost taglost simple event fired when the NFCTag detected by the adaptor moves out of range.
onpeerfound peerfound NFCPeerEvent with peer property set to the new NFCPeer object. detect a new NFCPeer
onpeerlost peerlost simple event fired when the NFCPeer detected by the adaptor moves out of range.

NFCTagEvent Interface

readonly attribute NFCTag tag
When getting, the user agent MUST return the NFCTag that triggered the event.

NFCPeerEvent Interface

readonly attribute NFCPeer peer
When getting, the user agent MUST return the NFCPeer that triggered the event.

NDEFMessageEvent Interface

readonly attribute NDEFMessage message
When getting, the user agent MUST return the NDEFMessage that triggered the event.

NFCTag Interface

Promise readNDEF()
Read NDEF data from the NFC tag. This method returns a new Promise that will notify the caller with the result of the operation, which is a NDEFMessage.
Promise writeNDEF(in NDEFMessage message)
Write a NDEF message on the NFC tag. This method returns a new Promise to notify the caller about the operation success or failure.
NDEFMessage message
The NDEF message to write on the NFC Tag

NFCPeer Interface

Promise sendNDEF(in NDEFMessage message)
Send a NDEF message to the NFC peer device. This method returns a new Promise to notify the caller about the operation success or failure.
NDEFMessage message
The NDEF message to send to the NFC peer device.
Promise startHandover(in HandoverType handoverType)
Initiates WiFi or Bluetooth pairing with the NFC peer-to-peer target. This method returns a new Promise to notify the caller about the operation success or failure.
HandoverType handoverType
Select "wifi" or "bluetooth" pairing.
attribute EventHandler onmessageread
The messageread event of type NDEFMessageEvent MUST be fired whenever a new NDEFMessage is sent by the peer device. The message property of the event MUST contain the corresponding NDEFMessage object.

Event handlers

The following are the event handlers (and their corresponding event handler types) that MUST be supported as attributes by the NFCPeer object.

event handler event name event type short description
onmessageread messageread NDEFMessageEvent with message property set to the new NDEFMessage object. fired when a NDEFMessage is sent by the peer device.

NDEFMessage Interface

A NDEFMessage contains one or more NDEFRecords.

readonly attribute NDEFRecord[] records
MUST return an array of all NDEFRecord objects part of the NDEF message.
Promise getBytes()
Get the binary representation of the NDEF message. This method returns a new Promise to notify the caller with the result of the operation, which is of type byte[] i.e. a Javascript Array of Number objects.

NDEFRecord Interface

readonly attribute TNF tnf
The record's 3-bit Type Name Format constant.
readonly attribute DOMString? type
A string identifier describing the type of the payload.
readonly attribute DOMString? id
An identifier for the record, in the form of a URI reference.
Promise getPayload()
Extract the binary payload of the NDEF record. This method returns a new Promise to notify the caller with the result of the operation, which is of type byte[] i.e. a Javascript Array of Number objects.

NDEFRecordEmpty Interface

Empty NDEF record with TNF 0x00. Record type and payload must be null.

Well-known

Well-known record types are defined in the "NFC Record Type Definition (RTD) Specification", NFC Forum, 2006. All well-known records have TNF 0x01.

NDEFRecordText Interface

TNF 0x01, Record type "T", see "NFC Text RTD Specification", NFC Forum, 2006.

readonly attribute DOMString text
The encoded text.
readonly attribute DOMString languageCode
The language code string value, followed by IANA[RFC 3066] (ex: en-US, ko-KR).
readonly attribute DOMString encoding
The encoding type MUST be either UTF-8 or UTF-16

NDEFRecordURI Interface

TNF 0x01, Record type "U", see "URI RTD Specification", NFC Forum, 2006.

readonly attribute DOMString uri
The URI string that will be stored in the payload.
          var record = NDEFRecordURI("http://w3c.org"); 
          // uri is stored payload as 0x03 + w3c.org          
          console.log(record.uri); // prints http://w3c.org
      

NDEFRecordSmartPoster Interface

TNF 0x01, Record type "Sp", see "Smart Poster RTD Specification", NFC Forum, 2006.

readonly attribute DOMString uri
The URI field of the Smart Poster record, REQUIRED by the NFC forum specification.
readonly attribute NDEFRecordText[]? titles
The title in different languages. There MUST NOT be more than one title record with the same language code string value.
readonly attribute SmartPosterAction? action
The possible actions defined by the NFC forum Smart Poster Record Type.
readonly attribute NDEFRecordMedia[]? icons
The Smart Poster Record can contain one or more icons, that can also be animated.
readonly attribute unsigned long? targetSize
The size of the URI target in bytes.
readonly attribute DOMString? targetMIME
The MIME type of the URI target.

Handover

TODO: should we use the generic NDEFRecord for Handover records: "ac", "Hc", "Hr", "Hs" or create specific subclasses?

NDEFRecordMedia Interface

Media records have TNF 0x02 and use a MIME Type to describe the contents of the payload. The "NFC Data Exchange Format (NDEF) Technical Specification", NFC Forum, 2006, specifies the MIME type should be in the format, as defined in [RFC 2046]. The mimeType in the constructor, is stored in type attribute of the NDEFRecord. The payload may be constructed as a byte[] or DOMString.

      var record = NDEFRecordMedia("application/json", '{"message" : "Hello, world"}');      
  

NDEFRecordAbsoluteURI Interface

Absolute URI records have TNF 0x03 and use a URI in the type field to describe the contents of the payload. The "NFC Data Exchange Format (NDEF) Technical Specification", NFC Forum, 2006, specifies the type should be an absolute-URI, as defined in [RFC 3986].

Note that the URI in an NDEFRecordAbsoluteURI describes the payload. Users who want to store a URI in an NDEFRecord should use NDEFRecordURI.

      // Windows LaunchApp Record
      
      // [00] 00 01 0C 57 69 6E 64 6F 77 73 50 68 6F 6E 65 26 |...WindowsPhone&|
      // [10] 7B 66 35 38 37 34 32 35 32 2D 31 66 30 34 2D 34 |{f5874252-1f04-4|
      // [20] 63 33 66 2D 61 33 33 35 2D 34 66 61 33 62 37 62 |c3f-a335-4fa3b7b|
      // [30] 38 35 33 32 39 7D 00 01 20                      |85329}.. |

      var payload = [ 
        0x00, 0x01, 0x0C, 0x57, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x50, 0x68, 0x6F, 0x6E, 0x65, 0x26,
        0x7B, 0x66, 0x35, 0x38, 0x37, 0x34, 0x32, 0x35, 0x32, 0x2D, 0x31, 0x66, 0x30, 0x34, 0x2D, 0x34,
        0x63, 0x33, 0x66, 0x2D, 0x61, 0x33, 0x33, 0x35, 0x2D, 0x34, 0x66, 0x61, 0x33, 0x62, 0x37, 0x62,
        0x38, 0x35, 0x33, 0x32, 0x39, 0x7D, 0x00, 0x01, 0x20
      ]
            
      var record = new NDEFRecordAbsoluteURI("windows.com/LaunchApp", payload);
  

NDEFRecordExternal Interface

External type records allow custom name spaces to be defined. External records have TNF 0x04. The external type begins with the reverse domain name followed by a colon and the type. The external type should be passed to the constructor without the urn:nfc:ext: prefix. The record type is defined in the "NFC Record Type Definition (RTD) Specification", NFC Forum, 2006, Section 2.2 NFC Forum External Type.

      // Android Application Record AAR
      var record = new NDEFRecordExternal("android.com:pkg", "com.nxp.nfc.tagwriter");
  

Record Chunking

When reading chunked content, implementations should combine TNF unchanged (0x06) records with the first chunk creating one logical NDEFRecord. Refer to "NFC Data Exchange Format (NDEF) Technical Specification" NFC Forum, 2006, Section 2.3.3 Record Chunks for more information.

Enumerations

NFC Type Name Format (TNF) constants are defined in the "NFC Data Exchange Format (NDEF) Technical Specification". The TNF field describes the format of the data in the record type field. The attribute tnf can have the following values:

Empty
0x00. Empty.
Well-known
0x01. NFC Forum well-known type as defined in the NFC RTD specification.
Media-type
0x02. Media-type as defined in RFC 2046
AbsoluteURI
0x03. Absolute URI as defined in RFC 3986
External
0x04. NFC Forum External type as defined in the NFC RTD specification.
Unknown
0x05. Unknown.
Unchanged
0x06. Unchanged.
Reserved
0x07. Reserved.

The attribute action can have the following values:

do
Do the action. For instance, send a SMS, dial a phone number, or open a URI.
save
Store a SMS, bookmark a URI, save a phone number in the address book.
open
Open for edition.

The attribute handoverType can have the following values:

wifi
Initiate WiFi handover.
bluetooth
Initiate bluetooth pairing.

Acknowledgements

The editors would like to thank Jaehyun Park and Taehee Lee of Samsung for their work on the initial API design. We would also like to thank the members of the W3C SysApps group for their help on the API specification process, and the members of the W3C NFC group for their feedback on this API.