My favorites | Sign in
Project Home Downloads Wiki Issues Source

Updated Feb 1, 2014 by

Why API mode?

XBees support two modes of operation: API and AT. In API mode, you communicate with the radio by sending and receiving packets. In AT (transparent) mode, the XBee radio simply relays serial data to the receiving XBee, as identified by the DH+DL address.

This software is designed solely for API mode. API mode is enabled by setting the AP parameter (Series 1), or uploading API firmware (Series 2). This software requires the AP mode set to 2 (escape bytes), as this setting offers the best reliability.

Here's a brief overview of the main advantages of API Mode vs. AT (Transparent Mode):

API (Packet) Mode

  • I/O Samples. This feature allows an XBee to receive I/O data from 1 or more remote XBees
  • Acknowledgement (ACK) and Retries. When sending a packet, the transmitting radio receives an ACK, indicating the packet was successfully delivered. The transmitting radio will resend the packet if it does not receive an ACK.
  • Receive packets (RX), contain the source address of transmitting radio
  • Configure a remote radio with the Remote AT feature
  • Easily address multiple radios and send broadcast TX packets
  • Obtain RSSI (signal strength) of an RX packet
  • Packets include a checksum for data integrity
  • ZigBee endpoints, cluster IDs and profile IDs (Series 2 XBee)

AT (Transparent) Mode

  • Simple
  • Compatible with any device that speaks serial
  • Primarily for point to point communication between two XBees. It's possible to communicate with multiple XBees but this requires entering command mode each time to change the destination address.

Series 1 radios support both AT and API modes with a single firmware version, allowing you switch between the modes with X-CTU. However, Series 2 requires a specific firmware for API mode. As of now there are two firmware versions for Series 2 API mode: ZNet and ZB Pro. ZNet is recommended as it is the easiest to work with.

Comment by, May 29, 2010

Can one (coordinator) xbee be configured with API mode using this software and tx/rx data from another xbee in transparent mode?

Comment by, Aug 14, 2010

Yes, this will work fine.

Comment by, Jan 12, 2011

but, why AP = 2 is better than AP =1 ?

Comment by, Feb 24, 2011

To configure ZNet/ZB Pro/Series 2

Prerequisites are

  • One ZNet or ZB Pro XBee with Coordinator API firmware
  • One ZNet or ZB Pro XBee with End Device API firmware

But if the xbee devices are in api mode i cant write to them using at commands. Any help would be much appreciated.

Comment by project member, Jul 18, 2011

You can, but you need to send AT commands in packet mode. So, use X-CTU and check the API mode checkbox (with escape characters), or write code with this library using the AtCommand? class. There are plenty examples.

Comment by, Jul 21, 2011

Hi, Can one gateway work with API mode?? How? please help me

Comment by, Oct 20, 2011

Can any one assist with configuration of three series 1 modules. Where two modules are for transmission of data and the other receives data from the other two modules?

Comment by, Jun 13, 2012


i need to switch on and off an LED connected on pin 20 (D0) on an end device xbee, whereas the coordinator is connected on a pc.

from now i have been trying to do so by these command in X-CTU :

+++ ATD04 ATCN

the problem is that both the coordinator and end device acts the same.

all what i want to do is to switch on the LED on the end device only.

can i have the configuration and code to do so?


Comment by, Jul 26, 2012

I've read before that with series 1 radios is not possible to implement mesh networks. But as I see in this article, mesh networks implementation it is posible simply use the API mode, regardless the radio serie?. Can anyone confirm this?


Comment by, Sep 25, 2012


I'am currently working on a school project, which requires me to work with the transport layer of the zigbee stack. So, i was wondering if this layer could be controlled from a Microcontroller instead of the normal zigbee transport layer in series 2 radios. ( I've Heard from a professor that in series 2 radios this is set and one cannot meddle with it ).

Comment by, Jan 25, 2013

hi i want to ask what is the method (in Java API) can retrieve the data bytes of the received packet if am using eclipse while sending API packets from arduino? am using S1 xbees.

thank you its very urgent that i know this.

Comment by, Feb 12, 2013


I am currently working on image transmission using Xbee Pro Series 1. But I am stuck in packet construction. Does anyone give me some guideline how to construct packets in API mode using Java.

Comment by, Feb 25, 2013

Hi I'm actually working on hacking this up to get it to work with Series 1 in series1 mode - yes I understand there are various issues, but this is for an MQTT net and I've augmented things somewhat :-/

So far, the only real issue I've run into with this mode is the escape characters, and surrounding the relevant escape logic in XBee:sendByte with #if SERIES_2 seems to make everyone happy - I've had a system reporting roomba sensor readings for over 24 hours with no issues

I've also added a class to support easier configuration from clients, and to allow for a more event driven architecture on the client side - I've appended the code below and can send it to you with doc lines once it's finalized - the bottom line is that clients implement the event handlers (TX16Handler,RX16Handler,TXFailureHandler,XBeeErrorHandler), set their loop to repeatedly call DutyCycle?() and use RequestSend? to ship data.

#define TRACING 1

class XBeeMessageSwitch16
  typedef void (*TX16Handler)(XBeeMessageSwitch16* messageSwitch);
  typedef void (*RX16Handler)(Rx16Response* theResponse);
  typedef void (*TXFailureHandler)(TxStatusResponse* theStatus);
  typedef void (*XBeeErrorHandler)(uint8_t errorCode);
  enum ETXState
  void Initialize(Stream* commPort,uint8_t* txPayloadBuffer,
					 RX16Handler rxHandlerFn,TX16Handler txHandlerFn,
				TXFailureHandler txFailureHandlerFn,XBeeErrorHandler xbErrorHandlerFn);
  void DutyCycle();
  inline bool IsTXAvailable() const { return txState == TXIdle; }
  void RequestSend(uint8_t* payload,uint8_t payloadLength,uint16_t address);
  inline bool isReadyToSend() const { return txState == TXRequested; }
  ETXState txState;
  XBee xbee;
  XBeeResponse response;
  Rx16Response response16;
  Tx16Request request16;
  TxStatusResponse txStatus16;
  unsigned long txTimestamp;
  uint16_t txAvailableDelay;
  RX16Handler rxHandler;
  TX16Handler txHandler;
  TXFailureHandler txFailureHandler;
  XBeeErrorHandler xbErrorHandler;

void XBeeMessageSwitch16::Initialize(Stream* commPort,uint8_t* txPayloadBuffer,
					 RX16Handler rxHandlerFn,TX16Handler txHandlerFn,
					 TXFailureHandler txFailureHandlerFn,XBeeErrorHandler xbErrorHandlerFn)
  rxHandler = rxHandlerFn;
  txHandler = txHandlerFn;
  txFailureHandler = txFailureHandlerFn;
  xbErrorHandler = xbErrorHandlerFn;
  txState = TXIdle;
void XBeeMessageSwitch16::RequestSend(uint8_t* payload,uint8_t payloadLength,uint16_t address)
  if(payload != NULL)
  txState = TXRequested;

void XBeeMessageSwitch16::DutyCycle()

      txTimestamp = millis();
      txState = TXUnconfirmed;
  else if(txState == TXIdle && txHandler != NULL)
      if(millis() - txTimestamp > txAvailableDelay)
	  txTimestamp = millis();
  // see if there's an inbound packet and process it

	case RX_16_RESPONSE :
      Serial.println("PACKET RECEIVED");Serial.flush();
	  if(rxHandler != NULL)

	  if(txStatus16.getStatus() == SUCCESS && txState == TXUnconfirmed)
      Serial.println("TX CONFIRM");Serial.flush();
	      txState = TXIdle;
	      txTimestamp = millis();
      Serial.println("TX FAIL");Serial.flush();
      txState = TXFailed;
	      if(txFailureHandler != NULL)
  else if(xbee.getResponse().isError())
      if(xbErrorHandler != NULL)
  // see how long we've been waiting on a tx confirmation
  if(txState == TXUnconfirmed)
      unsigned long ts = millis();
      // if it wrapped, just reset the timer
      if(ts < txTimestamp)
	txTimestamp = ts;
	  if(ts - txTimestamp > TXRESPONSEWINDOW)
#endif  	      txState = TXFailed;
	      if(txFailureHandler != NULL)

  if(txState == TXFailed)
      txState = TXIdle;
      txTimestamp = millis();
Comment by, Jul 18, 2013


My project is to control a wall plug with an arduino uno r2 and a relay. I want to control these with xbee s2 with a pc so i have to create a progam in Labview to monitoring the relay. I can't put the xbee's working on with labview. I have configured those in x-ctu and coolterm. I also can control the relay with x-ctu so i think que problem is in Labview. Could you help me please?

Best regards

Comment by, Sep 14, 2013

Please, I want to turn a Led on and OFF that connected in a Xbee series2 pin "that connected in a PC USB" by using Labview....Can U help me please !!

Comment by, Oct 24, 2013

Hi, I have a problem, I need configure a End_Device? Destination Address from the coordinator (configuration like a Over the air or something or something).

Best regards

Comment by, Apr 25, 2014

Hi, I'm trying to connect XBee Pro Series 2 with a non Digi modules. I have read in Digi documentation that only can do it if I work in API mode. There is other reason to work with API mode.

If I send a message from non Digi to Digi XBee I get the message, but if I send from XBee to non-Digi I couldn't read the message, any idea to solve it?

Comment by, May 4, 2014

hi i want to used this api with serial 1 but problem is that i didnt understand how to communicat node in api mode plz show me the way

Comment by, May 6, 2014

Hi, I have to xbee and one if connected to a digi module. the first one send gps cordinate to the seconde xbee. I can receive the data flow of cordinates with x-ctu but i can't use them in real-time, that's why I want to create a program to read and stock the data on a buffer in java with eclipse.

Do you have some advice for me ?



Comment by, Jun 11, 2014

Do you have any documents / tutorial to make it work with android


Comment by, Sep 14, 2014

Hi can you help me on why the sent packet generated from XCTU software is different from the packet received at XBee connected to Arduino. I'm totally confused here. The payload also has been changed. I'm using Series 2.

Sign in to add a comment
Powered by Google Project Hosting