# API Overview The Cloud-RF API offers a powerful and versatile system to model any radio, anywhere. ## Full OpenAPI 3 Schema For a complete OpenAPI 3 schema of the Cloud-RF API please consult the [Swagger UI documentation](https://cloudrf.com/documentation/developer/swagger-ui/). ## API Endpoint For most users the endpoint for the API is `https://api.cloudrf.com`. Users with a private server will have an IP address instead and API functions will be relative to this address. ### Security All requests are encrypted at the transport layer with TLS. ## Authentication Each user has a unique private API key which resembles a long random string of characters. An example of such API key is as below: ``` 101-ec94622a4cb939a77101a118c6871d03cea88af3 ``` ### API Key Security It is important to keep your API key secure. Publicly exposing your key can compromise your account, which could result in a loss of data or unexpected charges. To keep your API keys secure, follow some best practices: #### Keys as Environment Variables Store API keys as environment variables. This has an added benefit of accessing your key via a friendly environment variable name rather than having to remember your full key each time. **Do not embed API keys directly in code. API keys that are embedded in code can be accidentally exposed outside your circle of trust.** #### Keys as Files You can store your API key in a file and make reference to that file each time you need to use your API key. **If you store API keys in files, store those files outside your application's source tree.** Doing so helps to ensure that your keys do not end up in your source code version control system. This is particularly important if you use a public source code management system such as GitHub. ### Using the API Key The CloudRF API requires API key authentication in the request header. This provides a key-value pair with `key` as the first value and your personal key as the second, paired value. For example, [Postman](https://learning.postman.com/docs/sending-requests/authorization/#api-key) allows you to enter your key from their interface. ## Example API Requests Below lists some basic examples of some of the most common types of requests made to the Cloud-RF API. For a complete list of available schemas please consult the [Swagger UI documentation](https://cloudrf.com/documentation/developer/swagger-ui/). With all requests some values are required and so the response will return any validation errors or any failures should your request not be able to be processed. ### Area The `area` endpoint accepts a JSON object describing your network and will run a point-to-multipoint area calculation. The following example excludes some optional parameters and provides the required data to model a transmitter with many receivers at a height of 2 meters. The below example is sent as a `POST` request to `https://api.cloudrf.com/area`. ```json { "site": "A1", "network": "Testing", "transmitter": { "lat": 38.916, "lon": 1.448, "alt": 2, "frq": 868, "txw": 0.1, "bwi": 1 }, "receiver": { "lat": 0, "lon": 0, "alt": 2, "rxg": 3, "rxs": -100 }, "antenna": { "txg": 2.15, "txl": 1, "ant": 0, "azi": 1, "tlt": 10, "hbw": 2, "vbw": 2, "pol": "h" }, "environment": { "clt": "Minimal.clt", "elevation": 1, "landcover": 0, "buildings": 0, "obstacles": 0 }, "output": { "units": "metric", "col": "RAINBOW.dBm", "out": 2, "ber": 2, "mod": 7, "nf": -80, "res": 10, "rad": 5 } } ``` ### Path The `path` endpoint accepts a JSON object describing your network and will run a point-to-point calculation. The following example excludes some optional parameters and provides the required data to model a link with 1 receiver. Notice it looks very similar to the `area` call except for the receiver latitude (`lat`) and longitude (`lon`) values. The below example is sent as a `POST` request to `https://api.cloudrf.com/path`. ```json { "site": "A1", "network": "Testing", "transmitter": { "lat": 38.916, "lon": 1.448, "alt": 2, "frq": 868, "txw": 0.1, "bwi": 1 }, "receiver": { "lat": 38.91612, "lon": 1.49999, "alt": 2, "rxg": 3, "rxs": -100 }, "antenna": { "txg": 2.15, "txl": 1, "ant": 0, "azi": 1, "tlt": 10, "hbw": 2, "vbw": 2, "pol": "h" }, "environment": { "clt": "Minimal.clt", "elevation": 1, "landcover": 0, "buildings": 0, "obstacles": 0 }, "output": { "units": "metric", "col": "RAINBOW.dBm", "out": 2, "ber": 2, "mod": 7, "nf": -80, "res": 10, "rad": 5 } } ``` ### Points The `points` endpoint accepts a JSON object describing your network. The following example excludes some optional parameters and provides the required data to model an array of transmitters back to one receiver. With this structure you can test a polyline, route or lots of sensors talking to a single base station. The `transmitter` block contains a location but this is ignored when a points array is supplied. The below example is sent as a `POST` request to `https://api.cloudrf.com/points`. ```JSON { "site": "A1", "network": "Testing", "transmitter": { "lat": 38.916, "lon": 1.448, "alt": 2, "frq": 868, "txw": 0.1, "bwi": 1 }, "points": [ { "lat": 38.916, "lon": 1.411, "alt": 1 }, { "lat": 38.916, "lon": 1.411, "alt": 1 } ], "receiver": { "lat": 38.916, "lon": 1.448, "alt": 0.1, "rxg": 2.15, "rxs": -90 }, "antenna": { "txg": 2.15, "txl": 1, "ant": 0, "azi": 1, "tlt": 10, "hbw": 2, "vbw": 2, "pol": "h" }, "environment": { "clt": "Minimal.clt", "elevation": 1, "landcover": 0, "buildings": 0, "obstacles": 0 }, "output": { "units": "metric", "col": "RAINBOW.dBm", "out": 2, "ber": 2, "mod": 7, "nf": -80, "res": 10, "rad": 5 } } ``` ## More Information See more example requests and responses on the official API documentation on the Postman network at [https://docs.cloudrf.com](https://docs.cloudrf.com). For a complete OpenAPI 3 schema of the Cloud-RF API please consult the [Swagger UI documentation](https://cloudrf.com/documentation/developer/swagger-ui/). ### Compression CloudRF uses gzip compression for output files. The official client handles this but if you are writing your own you should use the MIME type rather than writing raw data as a .tiff may actually be .tiff.gz Python3: ``` # WARNING: Will write a gzipped file shutil.copyfileobj(response.raw, outputFile) # Will handle gzip decompression outputFile.write(response.content) ``` ### Verbose environment variables Since v3.8, the environment block has been redesigned to replace the cryptic cll,clm values with simpler boolean layers describing elevation, landcover, buildings and obstacles. This enables easier layering of custom clutter upon DTM for example (elevation = 2, obstacles = 1) Both methods are supported in 3.8 but the long form is now the standard, as used in the web interface, and the old trigraph method is deprecated. It still features in places such as templates. The following table translates old to new values: | Legacy value | New value (3.8) | | ----------- | ----------- | | cll = 0 | landcover = 0 | | cll = 1 | landcover = 1 | | cll = 2 | landcover = 1, buildings = 1 | | clm = 0 | obstacles = 0 | | clm = 1 | obstacles = 1 | | clm = 2 | elevation = 2, obstacles = 1 | ## Example Scripts A list of ready-to-use scripts are available on the [Cloud-RF public GitHub repository](https://github.com/Cloud-RF/CloudRF-API-clients/). - [Python](https://github.com/Cloud-RF/CloudRF-API-clients/tree/master/APIv2/python) - [Bash](https://github.com/Cloud-RF/CloudRF-API-clients/tree/master/APIv2/bash) ## Example cURL Request and Response The below shows an example cURL request to the `points` endpoint. Please note the API `key` sits within the header, not the data. ```curl curl --location --request POST 'https://api.cloudrf.com/points' \ --header 'key: 101-IBIZA.DEMO.KEY' \ --data-raw '{ "site": "Points", "network": "Testing", "transmitter": { "lat": 38.916, "lon": 1.448, "alt": 1, "frq": 868, "txw": 0.1, "bwi": 0.1 }, "points": [ { "lat": 38.916, "lon": 1.411, "alt": 1 }, { "lat": 38.916, "lon": 1.411, "alt": 1 } ], "antenna": { "txg": 2.15, "txl": 0, "ant": 1, "azi": 0, "tlt": 0, "hbw": 0, "vbw": 0, "pol": "v" }, "receiver": { "lat": 38.916, "lon": 1.448, "alt": 0.1, "rxg": 2.15, "rxs": -90 }, "model": { "pm": 1, "pe": 2, "cli": 6, "ked": 0, "rel": 95, "ter": 4 }, "environment": { "clt": "Minimal.clt", "elevation": 1, "landcover": 0, "buildings": 0, "obstacles": 0 }, "output": { "units": "metric", "col": "RAINBOW.dBm", "out": 2, "ber": 0, "mod": 0, "nf": -114, "res": 10, "rad": 5 } }' ``` The API output is JSON which can be easily parsed by any language. Using the previous request to `points` we get the following response. ```json { "Engine": "Sleipnir 1.6.1", "Frequency MHz": 868, "Propagation model": "ITM", "Earth dielectric constant": 13, "Earth conductivity": 0.002, "Radio climate": "Maritime Temperate (Land)", "Atmospheric bending constant": 301, "Fraction of situations": 95, "Fraction of time": 95, "Receiver": [ { "Latitude": 38.916, "Longitude": 1.448, "Ground elevation m": 0, "Antenna height m": 0.1, "Receiver gain dBd": 0, "Receiver gain dBi": 2.15 } ], "Transmitters": [ { "Latitude": 38.916, "Longitude": 1.411, "Ground elevation m": 58, "Antenna height m": 1, "Distance to receiver km": 3.205, "Azimuth to receiver deg": 89.99, "Downtilt angle deg": 1.1, "Antenna gain dBd": 0, "Antenna gain dBi": 2.15, "Polarisation": "Vertical", "Power W": 0.1, "Power dBm": 25.47, "ERP W": 0.22, "EIRP W": 0.16, "ERP dBm": 23.32, "EIRP dBm": 25.47, "Free space path loss dB": 97, "Bandwidth MHz": 0.1, "Johnson Nyquist noise dB": 0.2, "Noise floor dBm": -114, "Channel noise dBm": -113.8, "Signal power at receiver dBm": -294.1, "Signal to Noise Ratio dB": -180.3, "Computed path loss dB": 314.1, "Model attenuation dB": 217.1, "Field strength at receiver dBuV/m": -152.6, "Raise RX antenna for LOS": 18.1, "Raise RX antenna for fresnel 60%": 159.1, "Raise RX antenna for full fresnel": 321.1, "server": 1 }, { "Latitude": 38.916, "Longitude": 1.411, "Ground elevation m": 58, "Antenna height m": 1, "Distance to receiver km": 3.205, "Azimuth to receiver deg": 89.99, "Downtilt angle deg": 1.1, "Antenna gain dBd": 0, "Antenna gain dBi": 2.15, "Polarisation": "Vertical", "Power W": 0.1, "Power dBm": 22.15, "ERP W": 0.1, "EIRP W": 0.16, "ERP dBm": 20, "EIRP dBm": 22.15, "Free space path loss dB": 97, "Bandwidth MHz": 0.1, "Johnson Nyquist noise dB": 0.2, "Noise floor dBm": -114, "Channel noise dBm": -113.8, "Signal power at receiver dBm": -294.1, "Signal to Noise Ratio dB": -180.3, "Computed path loss dB": 314.1, "Model attenuation dB": 217.1, "Field strength at receiver dBuV/m": -156, "Raise RX antenna for LOS": 18.1, "Raise RX antenna for fresnel 60%": 159.1, "Raise RX antenna for full fresnel": 321.1, "server": 2 } ], "calculation_adjusted": [], "elapsed": 45.0, "kmz": "https://api.cloudrf.com/API/archive/data?points=0810163833_Testing_POINTS&uid=101", "json": "https://api.cloudrf.com/users/101/0810163833_Testing_POINTS.json" } ```