The codecs API serves the codec library and your own codecs to people, scripts and licensed routers. Use it to keep codecs in version control, to publish them from a pipeline, or to test payloads from your own tools.
Paths below follow the usual form https://<your host>/tenant/<tenantId>/api/…. Send an API key as Authorization: Bearer <API key>. See REST API basics.
Routes
| Method and path | Permission | Answer |
|---|---|---|
GET /api/iot/lorawan/codecs | Optional (see below) | The codec index: { version, scope, codecs: [...], sig: null } |
GET /api/iot/lorawan/codecs/<codecId> | Optional | One codec: { id, rev, sha256, scope, document, outputSet } |
GET /api/iot/lorawan/codecs/bundle | Optional | Every codec with its document, compressed: { version, codecs: [{ id, rev, sha256, scope, document }] } |
GET /api/iot/lorawan/codec-library | View codecs | The list the codecs drawer shows (paged, sortable, both sources) |
POST /api/iot/lorawan/codecs | Manage codecs | Publish a new codec (201) |
PATCH /api/iot/lorawan/codecs/<codecId> | Manage codecs | Publish a new revision of your codec |
DELETE /api/iot/lorawan/codecs/<codecId> | Manage codecs | Delete your codec |
POST /api/iot/lorawan/codecs/<codecId>/test | View codecs | Decode one frame with a saved codec |
POST /api/iot/lorawan/codecs/test | View codecs | Check a codec document and optionally decode one frame; nothing is stored |
GET /api/iot/lorawan/codecs/<codecId>/revisions | View codecs | The codec’s revisions |
“View codecs” is the permission to view LoRaWAN codecs and run the test bench (users by default). “Manage codecs” is the permission to add, change and delete your own codecs (administrators by default).
Who sees what on the three read routes
| Credential sent | Answer |
|---|---|
| None | The public library only. Cached for 5 minutes (Cache-Control: public, max-age=300). |
| A valid session or API key with the view permission | The library plus your organisation’s codecs. Not cached (private, no-store). |
| A licensed router’s signed request | The library plus the codecs of the router’s organisation. |
| A credential that is present but wrong (bad header, expired session, unknown key) | 401 with invalid_credentials, signature_expired or certificate_revoked. Never the public list. |
| A valid credential without the permission | 403 |
Filters and caching
The index takes q (search), vendor, model, oui, fport and scope. Each answer carries an ETag equal to the index version; send it back in If-None-Match to get 304 Not Modified when nothing changed.
GET …/codecs/<codecId>?sha256=<fingerprint> asks for one exact revision. A withdrawn codec answers 410 (codec_withdrawn).
Publish a codec
POST /tenant/<tenantId>/api/iot/lorawan/codecs
Content-Type: application/json
{ "document": { "id": "t.room-sensor", "title": "…", "vendor": "…", "kind": "layout", "frames": [ … ], "tests": [ … ] } }
Or copy a library codec:
{ "copyOf": "<library codec id>", "id": "t.my-copy" }
The answer is 201 { codec, indexVersion }. Library codecs cannot be changed or deleted through these routes: 403 codec_read_only.
Test a frame
POST /tenant/<tenantId>/api/iot/lorawan/codecs/t.room-sensor/test
Content-Type: application/json
{ "fport": 2, "hex": "0BC4010A32" }
fport is 1–255 and hex at most 255 bytes. An invalid frame answers Enter the FPort (1-255) and the payload as hexadecimal digits (at most 255 bytes).
Rate limits
| Caller | Limit |
|---|---|
| No credential: index and single codec | 60 requests a minute per address |
| No credential: bundle | 6 an hour per address |
| Signed-in users and API keys | 240 a minute; bundle 30 an hour |
| Licensed routers | 120 a minute per device certificate |
Beyond a limit the API answers 429 (Too many requests. Try again later.).
Error codes
| Status | details.reason | Meaning |
|---|---|---|
| 404 | — | Codec not found. |
| 409 | codec_exists | A codec with this id already exists. Choose another id. |
| 410 | codec_withdrawn | This codec revision was withdrawn. |
| 403 | codec_read_only | Library codecs are not edited here: save a copy and change the copy. |
| 422 | codec_format_not_supported | A JavaScript decoder was sent. |
| 422 | codec_tests_failed | Test vectors failed; the failing vectors are listed. |
| 422 | codec_incompatible | The new revision removes keys or changes units. |
| 422 | codec_model_claimed | Another of your codecs covers this model. |
| 422 | codec_choice_unknown | (When a device or profile chooses a codec) the codec does not exist or was withdrawn. |
| 401 | invalid_credentials | The credentials sent with this request are not valid. |
For the full LoRaWAN API (gateways, devices, keys, pairing, frames), see the LoRaWAN API.

