Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Generic Erlang CoAP Client/Server

Pure Erlang implementation of the Constrained Application Protocol (CoAP), which aims to be conformant with:

The following features are not (yet) implemented:

  • Proxying and virtual servers (Uri-Host, Uri-Port, Proxy-Uri and Proxy-Scheme options)

It was tested with the following CoAP implementations:

Used in the following applications:

Let me know if you (intend to) use gen_coap. The API may change and some functions may not be implemented. Please add an Issue if you find a bug or miss a feature.


gen_coap enables you to integrate a CoAP server and/or CoAP client with your application. For demonstration purposes it also includes a simple CoAP client and server.

Build Status


Have a look at sample_client.erl. It implements a simple command line utility for manipulation and observation of CoAP resources. It shall demonstrate the use of the coap_client and coap_observer modules. The tool accepts the following arguments:

Argument Description
-m Method request method (get, put, post or delete), default is 'get'
-e Text include text as payload
-s Duration subscribe for given duration [seconds]
Uri coap:// or coaps:// URI identifying the resource

Run the example simply by:

$ ./ coap://
$ ./ coaps://
$ ./ coaps://
$ ./ coap:// -s 1000
$ ./ -m put coap:// -e data
$ ./ -m delete coap://

In an erlang program you can get a CoAP resource by:

{ok, content, Data} = coap_client:request(get, "coap://")

No application need to be started to use the client.


Have a look at sample_server.erl. It implements a simple resource storage, which can be accessed using CoAP. It shall demonstrate the use of the coap_server_registry and coap_responder modules. The server requires no arguments. Run the sample server as follows and then access it using any CoAP client (or the gen_coap sample client tool):

$ ./

You can manually start the server from the Erlang command line by:

$ erl -pa _build/default/lib/gen_coap/ebin

1> application:ensure_all_started(gen_coap).

2> coap_server:start_udp(coap_udp_socket).

However, the server out of a box does not offer any resources. To offer CoAP access to some server resources you need to implement the coap_resource behaviour, which defines callbacks that the server invokes upon reception of a CoAP request.

  • coap_discover is called when a CoAP client asks for the list of ".well-known/core" resources.
  • coap_get, coap_post, coap_put or coap_delete is called when the server receives a GET, POST, PUT or DELETE request for a resource.
  • coap_observe or coap_unobserve is called upon a GET request with an Observe=0 or Observe=1 option.

Since Erlang 19.2 the DTLS transport is supported. To configure certificates for the sample coap-server do:

$ cd gen_coap
$ sudo openssl req -new > csr.pem
$ sudo openssl rsa -in privkey.pem -out key.pem
$ sudo openssl x509 -in csr.pem -out cert.pem -req -signkey key.pem


The following picture shows the gen_coap modules are their relationships: GitHub Logo

Build Instructions


First, you need to have rebar installed. Please install the rebar package e.g. by

$ sudo yum install erlang-rebar

Then, you only need to run

$ git clone
$ cd gen_coap
$ make


I recommend you install the Erlang IDE for Eclipse. Then, import the project:

  • Run Eclipse, select File > New > Project..., select Erlang Project and click Next.
  • Enter gen_coap as a Project name and select Location of gen_coap on your machine. Click Next.
  • Review the following page and click Next.
  • Set Source folders to src;examples and click Finish.

Run the Erlang application and then you should be able to run the client and server in your Console:

1> sample_server:start().

2> sample_client:start(["coap://localhost/.well-known/core"]).
get "coap://localhost/.well-known/core"