{"openapi":"3.1.0","info":{"title":"Things LoRa Downlinks API","description":"This specification describes the LoRa Downlinks API of the KPN Things Platform.","contact":{"name":"KPN Things Support","url":"https://portal.kpnthings.com/support","email":"iot-developer@kpn.com"},"version":"0.8.0"},"servers":[{"url":"https://api.kpnthings.com","description":"Things API Environment"}],"paths":{"/lora/downlinks":{"get":{"summary":"Retrieve LoRa downlinks filtered and sorted by specified search and sort criteria","operationId":"searchDownlinks","parameters":[{"$ref":"#/components/parameters/cursor"},{"$ref":"#/components/parameters/limit"},{"$ref":"#/components/parameters/sort"},{"name":"deviceId","in":"query","description":"Include only downlinks for the device with the provided deviceId. The deviceId must match exactly.","style":"form","explode":true,"schema":{"$ref":"#/components/schemas/DeviceId","example":null},"example":"f24108fa-d102-40ff-8263-f8d46908a386"},{"name":"createdBefore","in":"query","description":"Include only LoRa downlinks created before the provided date and time. The date-time must be in ISO 8601 format.","style":"form","explode":true,"schema":{"type":"string","format":"date-time","example":null},"example":"2023-10-01T00:00:00Z"},{"name":"createdSince","in":"query","description":"Include only LoRa downlinks at or after the provided date and time. The date-time must be in ISO 8601 format.","style":"form","explode":true,"schema":{"type":"string","format":"date-time","example":null},"example":"2023-10-01T00:00:00Z"},{"name":"modifiedBefore","in":"query","description":"Include only LoRa downlinks modified before the provided date and time. The date-time must be in ISO 8601 format.","style":"form","explode":true,"schema":{"type":"string","format":"date-time","example":null},"example":"2023-10-01T00:00:00Z"},{"name":"modifiedSince","in":"query","description":"Include only LoRa downlinks modified at of after the provided date and time. The date-time must be in ISO 8601 format.","style":"form","explode":true,"schema":{"type":"string","format":"date-time","example":null},"example":"2023-10-01T00:00:00Z"},{"name":"status","in":"query","description":"Include only LoRa downlinks whose status matches the provided status. The status must match exactly.","style":"form","explode":true,"schema":{"type":"string","enum":["PENDING","EXECUTING","DONE"],"example":null},"example":"PENDING"}],"responses":{"200":{"description":"Page of filtered LoRa downlinks. Only downlinks that are accessible to the caller are returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageOfLoraDownlinks","example":null}}}}},"security":[{"BearerAuth":["downlink.read"]}]},"post":{"summary":"Create a new LoRa downlink","operationId":"createDownlink","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoraDownlink","example":null}}}},"responses":{"201":{"description":"LoRa downlink has been successfully created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoraDownlink","example":null}}}}},"security":[{"BearerAuth":["downlink.write"]}]}},"/lora/downlinks/{downlinkId}":{"get":{"summary":"Retrieve a LoRa downlink by ID","operationId":"getDownlink","parameters":[{"name":"downlinkId","in":"path","description":"LoRa downlink identifier.","required":true,"style":"simple","schema":{"type":"string","format":"uuid","example":null}}],"responses":{"200":{"description":"The LoRa downlink.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoraDownlink","example":null}}}}},"security":[{"BearerAuth":["downlink.read"]}]},"delete":{"summary":"Accepts and schedules full or partial cancellation of a LoRa downlink for further downstream handling.","operationId":"cancelDownlink","parameters":[{"name":"downlinkId","in":"path","description":"LoRa downlink identifier.","required":true,"style":"simple","schema":{"type":"string","format":"uuid","example":null}},{"name":"forced","in":"query","description":"Whether to force the cancellation of the LoRa downlink or not.","style":"form","explode":true,"schema":{"type":"boolean","default":false,"example":null}}],"responses":{"202":{"description":"LoRa downlink cancellation has been accepted and scheduled for further downstream processing."},"409":{"description":"LoRa downlink status does not permit cancellation.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem","example":null}}}}},"security":[{"BearerAuth":["downlink.delete"]}]}}},"components":{"schemas":{"DeviceId-uuid":{"type":"string","format":"uuid","description":"Things Device UUID","example":"478a82d4-128f-47a6-aa61-2eac3f2a23ad","title":"UuidDeviceId"},"DeviceId-imei":{"type":"string","description":"IMEI-based device ID","example":"imei:350266800610993","pattern":"(?i)^imei:[0-9]{15,16}$","title":"ImeiDeviceId"},"DeviceId-deveui":{"type":"string","description":"LoRaWAN DevEUI device ID","example":"deveui:ea8fa35e2cf3489f","pattern":"(?i)^deveui:[a-f0-9]{16}$","title":"DevEuiDeviceId"},"DeviceId-dvnuuid":{"type":"string","description":"DVNUUID-based device ID","example":"dvnuuid:ed8b73ac-f48f-4457-8ccc-9926cf28979f","pattern":"(?i)^dvnuuid:[a-f0-9]{8}(-[a-f0-9]{4}){3}-[a-f0-9]{12}?$","title":"DvnUuidDeviceId"},"DeviceUrn-imei":{"type":"string","description":"IMEI-based device URN","example":"urn:dev:imei:350266800610993","pattern":"(?i)^urn:dev:imei:[0-9]{15,16}:?$","title":"ImeiDeviceUrn"},"DeviceUrn-deveui":{"type":"string","description":"LoRaWAN DevEUI device URN","example":"urn:dev:deveui:ea8fa35e2cf3489f","pattern":"(?i)^urn:dev:deveui:[a-f0-9]{16}:?$","title":"DevEuiDeviceUrn"},"DeviceUrn-dvnuuid":{"type":"string","description":"DVNUUID-based device URN","example":"urn:dev:dvnuuid:ed8b73ac-f48f-4457-8ccc-9926cf28979f","pattern":"(?i)^urn:dev:dvnuuid:[a-f0-9]{8}(-[a-f0-9]{4}){3}-[a-f0-9]{12}:?$","title":"DvnUuidDeviceUrn"},"DeviceId":{"type":"string","format":"device-id","description":"A device identifier in one of several supported formats.","oneOf":[{"$ref":"#/components/schemas/DeviceId-uuid","example":null},{"$ref":"#/components/schemas/DeviceId-imei","example":null},{"$ref":"#/components/schemas/DeviceId-deveui","example":null},{"$ref":"#/components/schemas/DeviceId-dvnuuid","example":null},{"$ref":"#/components/schemas/DeviceUrn-imei","example":null},{"$ref":"#/components/schemas/DeviceUrn-deveui","example":null},{"$ref":"#/components/schemas/DeviceUrn-dvnuuid","example":null}],"title":"DeviceId","example":null},"Page":{"type":"object","description":"Page of items","properties":{"items":{"type":"array","items":{},"example":null},"next":{"type":"string","format":"uri","description":"Pagination link pointing to the next page. Only provided when not at the last page.","example":null},"prev":{"type":"string","format":"uri","description":"Pagination link pointing to the previous page. Only provided when not at the first page.","example":null}},"required":["items"],"title":"Page","example":null},"PayloadHexMessage":{"type":"object","description":"The message to send to the LoRa device","properties":{"payloadHex":{"type":"string","description":"Hex-encoded payload","pattern":"^[0-9a-fA-F]+$","example":null},"fPort":{"type":"integer","description":"LoRaWAN FPort used by the device for this downlink.","example":3}},"required":["fPort","payloadHex"],"title":"PayloadHexMessage","example":null},"DownlinkStatus":{"type":"string","description":"The status of the LoRa downlink. Known values include: PENDING, EXECUTING and DONE","example":"EXECUTING","readOnly":true,"title":"DownlinkStatus"},"SimpleDuration":{"type":"string","format":"duration","description":"Duration that supports a subset of ISO 8601, where only days, hours, minutes, and seconds can be specified. Days are treated as exactly 24 hours, thus ignoring daylight savings effects.","example":"P3DT4H5M6.5S","pattern":"^P(?:(\\d+D)(T(?:(\\d+H)?(\\d+M)?(\\d+(\\.\\d{1,9})?S)?)?)|T(\\d+H)?(\\d+M)?(\\d+(\\.\\d{1,9})?S)?)$"},"DownlinkFailureReason":{"type":"string","description":"The failure reason of the LoRa downlink. Known values include: CANCELLED, FEEDBACK_TIMEOUT, NOT_ACKNOWLEDGED_BY_DEVICE, FAILED_TO_TRANSMIT_TO_DEVICE, FAILED_TO_ENQUEUE_FOR_TRANSMISSION and EVICTED","example":"FEEDBACK_TIMEOUT","readOnly":true,"title":"DownlinkFailureReason"},"LoraDownlink":{"type":"object","description":"A downlink that is sent to a LoRa IoT device.","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the downlink.","example":"12345678-1234-1234-1234-123456789012","readOnly":true},"message":{"$ref":"#/components/schemas/PayloadHexMessage","example":null},"status":{"$ref":"#/components/schemas/DownlinkStatus","example":null},"retryLimit":{"type":"integer","default":0,"description":"The maximum number of retries that should be performed for the downlink.","example":3,"minimum":0},"retryCount":{"type":"integer","description":"The number of retries that have been performed for the downlink.","example":0,"minimum":0,"readOnly":true},"deviceId":{"$ref":"#/components/schemas/DeviceId","description":"The device identifier which this downlink is targeting.","example":"014388b0-5244-4ced-9fbf-1088c1c0d328"},"createdAt":{"type":"string","format":"date-time","description":"The timestamp when the downlink was created in the system.","example":"2025-04-01T00:00:00.000Z","readOnly":true},"modifiedAt":{"type":"string","format":"date-time","description":"The timestamp when the downlink was last modified in the system.","example":"2025-05-01T00:00:00.000Z","readOnly":true},"feedbackTimeout":{"allOf":[{"$ref":"#/components/schemas/SimpleDuration","example":null},{"description":"The duration after which feedback is expected for the downlink. Must be at least 10 minutes.","example":"PT25H"}],"example":null},"dryRun":{"type":"boolean","default":false,"description":"Indicates if this is a dry run.","example":null},"lastFailureReason":{"$ref":"#/components/schemas/DownlinkFailureReason","example":null}},"required":["deviceId","feedbackTimeout","message"],"title":"LoraDownlink","example":null},"PageOfLoraDownlinks":{"type":"object","allOf":[{"$ref":"#/components/schemas/Page","example":null},{"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/LoraDownlink"},"example":null}},"example":null}],"description":"A paginated list of LoRa downlinks.","title":"PageOfLoraDownlinks","example":null},"Problem":{"type":"object","description":"Error information details","properties":{"type":{"type":"string","format":"uri-reference","default":"about:blank","description":"A URI reference that uniquely identifies the problem type only in the\ncontext of the provided API. Opposed to the specification in RFC-9457,\nit is neither recommended to be dereferenceable and point to a\nhuman-readable documentation nor globally unique for the problem type.","example":"/some/uri-reference"},"title":{"type":"string","description":"A short summary of the problem type. Written in English and readable\nfor engineers, usually not suited for non technical stakeholders and\nnot localized.","example":"some title for the error situation"},"status":{"type":"integer","format":"int32","description":"The HTTP status code generated by the origin server for this occurrence\nof the problem.","example":"400","exclusiveMaximum":600,"minimum":100},"detail":{"type":"string","description":"A human readable explanation specific to this occurrence of the\nproblem that is helpful to locate the problem and give advice on how\nto proceed. Written in English and readable for engineers, usually not\nsuited for non technical stakeholders and not localized.","example":"Some description for the error situation"},"instance":{"type":"string","format":"uri-reference","description":"A URI reference that identifies the specific occurrence of the problem,\ne.g. by adding a fragment identifier or sub-path to the problem type.\nMay be used to locate the root of this problem in the source code.","example":"/some/uri-reference#specific-occurrence-context"}},"title":"Problem","example":null}},"parameters":{"cursor":{"name":"cursor","in":"query","description":"String that encodes all necessary information to retrieve a page.","style":"form","explode":true,"schema":{"type":"string","format":"cursor"}},"limit":{"name":"limit","in":"query","description":"Limit the number of results (per page).","style":"form","explode":true,"schema":{"type":"integer","default":50}},"sort":{"name":"sort","in":"query","description":"Sorting fields separated by comma. Default order is Ascending (ASC), minus(-) should be used in front of field name for Descending (DESC) order.","style":"form","explode":true,"schema":{"type":"string"},"example":"createdAt,-name"}},"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}}}