# Freebox OS API > Freebox OS API 16.1: the HTTP API of the Freebox, used on the local network (http://mafreebox.freebox.fr/api/v16/) or remotely over HTTPS. Calls are authenticated with a session token in the `X-Fbx-App-Auth` header, obtained from an app token through the `/login/` challenge (HMAC-SHA1). Responses are wrapped in a JSON envelope `{ "success": true, "result": ... }`, errors in `{ "success": false, "error_code": ..., "msg": ... }`. This text is generated by freebox-openapi 0.2.0 from the documentation served by the Freebox. Objects and operations (types, paths, parameters) follow the OpenAPI description (https://freebox.davlgd.com/openapi.json), which corrects errors of the original documentation: such places are marked **Correction** with the call used to check them. Examples are those of the documentation, repaired into valid JSON where possible (otherwise kept as text); they may contradict the operation they illustrate. Error codes are listed in the error table of each section. FreeboxOS Gateway APi allow access to Freebox Server settings and apps. This API can be used to develop companion apps for Smartphone, or provide an alternative to FreeboxOS web app. ## General Information ### API Version Api version will always use the following format : “major.minor” where major and minor are integers Current API version is “16.1” Current major API version is: 16 When an API is marked as *unstable*, you can use it but it may change or disappear at any time! When an API is not documented you should not use it! Other API will be maintained for at least 1 Freebox release. ### Freebox discovery To discover a Freebox supporting this API you can either use mDNS, or make a HTTP request to mafreebox.freebox.fr to get API information. #### Discovery using mDNS This is the preferred method since it does not require to know the Freebox IP address. The Freebox broadcasts the “_fbx-api._tcp” service On iOS devices, you can use a [NSNetServiceBrowser](https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSNetServiceBrowser_Class/Reference/Reference.html) On Android devices, you can use [Network Service Discovery](http://developer.android.com/training/connect-devices-wirelessly/nsd.html) or [JmDNS](http://sourceforge.net/projects/jmdns/) On the TXT record you can obtain the following information: | Key | Description | | --- | --- | | api_version | The current API version on the Freebox | | device_type | (DEPRECATED: use box_model) | | api_base_url | The API root path on the HTTP server | | uid | The device unique id | | api_domain | The domain to use in place of hardcoded Freebox ip | | https_available | Tells if https has been configured on the Freebox | | https_port | Port to use for remote https access to the Freebox Api | | box_model_name | Box model display name | | box_model | Box model | Currently the existing box models are | box_model | Description | | --- | --- | | fbxgw-r1/full | Freebox Server (v6) revision 1 | | fbxgw-r2/full | Freebox Server (v6) revision 2 | | fbxgw-r1/mini | Freebox Mini revision 1 | | fbxgw-r2/mini | Freebox Mini revision 2 | | fbxgw-r1/one | Freebox One revision 1 | | fbxgw-r2/one | Freebox One revision 2 | | fbxgw7-r1/full | Freebox v7 revision 1 | | fbxgw8-r1/full | Freebox v8 revision 1 | | fbxgw9-r1/full | Freebox v9 revision 1 | #### Discovery using HTTP If you can, avoid this method because it requires to use a hardcoded address to retrieve API information. If you make a HTTP get request on http://mafreebox.freebox.fr/api_version you can get the same API information as provided in mDNS. **Example request**: ```http GET /api_version HTTP/1.1 Host: mafreebox.freebox.fr ``` **Example response**: ```json { "uid": "23b86ec8091013d668829fe12791fdab", "device_name": "Freebox Server", "box_model": "fbxgw7-r1/full", "box_model_name": "Freebox v7 (r1)", "api_version": "16.1", "api_base_url": "/api/", "api_domain": "example.fbxos.fr", "https_available": true, "https_port": 3615 } ``` Only the fields available to build the API request URL (see below) are available if you connect remotely. #### Discovery using HTTPS Discovery using HTTPS works the same as discovery on HTTP. You can do an HTTP GET request on https://mafreebox.freebox.fr/api_version . You need to validate the certificate as explained below in HTTPS access. Discovery using HTTPS is preferred to HTTP discovery if you can’t use mDNS. You MUST implement the certificate validation in your app in order to use the API. ### Building the API request URL Once you’ve discovered a Freebox on the local network you can access the API at the following URL: ```text https://[api_domain]:[freebox_port]/[api_base_url]/v[major_api_version]/[api_url] ``` or for local access https://mafreebox.freebox.fr/[api_base_url]/v[major_api_version]/[api_url] **Example**: ```text https://example.fbxos.fr:3615/api/v16/login/ ``` ### Remote connection port change discovery When the https connection fails to a previously recorded https://[api_domain]:[https_port], you should attempt to discover if https_port has changed. This can happen either automatically (port is no longer valid), or manually if the user decided to change the port. The https port is announced in a DNS “_https._tcp” **SRV** record. For example, for domain [example.fbxos.fr], the SRV record will be: ```text # _service._proto.name. TTL class SRV priority weight port target _https._tcp.example.fbxos.fr 300 IN SRV 13 37 12345 example.fbxos.fr ``` Here, only the “port” field of the SRV record is relevant, i.e **12345**. The SRV field is only populated for the https port, and only for the [api_domain] field of the API information. Port change discovery is important to maintain remote connectability. ### API conventions Most API uses the [REST architecture](http://en.wikipedia.org/wiki/Representational_State_Transfer), pay attention to the http methods used for each request. For requests with a body, you must use “application/json” content-type unless otherwise stated. The API response is always a JSON object using utf8 encoding. #### Object `APIResponse` | Property | Type | Access | Description | | --- | --- | --- | --- | | `success` | boolean | read-only | indicates if the request was successful | | `result` | object | read-only | the result of the request. (It may be omitted if the request does not expect any result) | | `error_code` | string | read-only | In case of request error, this error_code provides information about the error. The possible error_code values are documented for each API. | | `msg` | string | read-only | In cas of error, provides a French error message relative to the error | **Successful response example** ```json { "success": true, "result": { "logged_in": false, "challenge": "WpsbHdkBpRpHLMGQHZ1ri1uUqa4ce6Dw" } } ``` **Error response example** ```json { "msg": "Requête invalide", "success": false, "error_code": "invalid_request" } ``` The HTTP response code can also be used to error reason, for instance if you attempt to access to an API with invalid credential you will get a 403 error, or if you attempt to call an API with an invalid path you will get a 404 error. ## HTTPS Access Each Freebox is now automatically assigned a random domain name (api_domain), and an associated TLS certificate to enable secure access to API. This is enabled by default and all applications MUST now use HTTPS to access the api. Unsecure access will be removed at some point. Certificates used for HTTPS access are emitted by either ‘Freebox ECC Root CA’ in case of ECDSA access, or ‘Freebox Root CA’ in case of RSA. You must validate the certificate chain, by using the following Root CA certificates: **Freebox ECC Root CA** ```lua -----BEGIN CERTIFICATE----- MIICWTCCAd+gAwIBAgIJAMaRcLnIgyukMAoGCCqGSM49BAMCMGExCzAJBgNVBAYT AkZSMQ8wDQYDVQQIDAZGcmFuY2UxDjAMBgNVBAcMBVBhcmlzMRMwEQYDVQQKDApG cmVlYm94IFNBMRwwGgYDVQQDDBNGcmVlYm94IEVDQyBSb290IENBMB4XDTE1MDkw MTE4MDIwN1oXDTM1MDgyNzE4MDIwN1owYTELMAkGA1UEBhMCRlIxDzANBgNVBAgM BkZyYW5jZTEOMAwGA1UEBwwFUGFyaXMxEzARBgNVBAoMCkZyZWVib3ggU0ExHDAa BgNVBAMME0ZyZWVib3ggRUNDIFJvb3QgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNi AASCjD6ZKn5ko6cU5Vxh8GA1KqRi6p2GQzndxHtuUmwY8RvBbhZ0GIL7bQ4f08ae JOv0ycWjEW0fyOnAw6AYdsN6y1eNvH2DVfoXQyGoCSvXQNAUxla+sJuLGICRYiZz mnijYzBhMB0GA1UdDgQWBBTIB3c2GlbV6EIh2ErEMJvFxMz/QTAfBgNVHSMEGDAW gBTIB3c2GlbV6EIh2ErEMJvFxMz/QTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB /wQEAwIBhjAKBggqhkjOPQQDAgNoADBlAjA8tzEMRVX8vrFuOGDhvZr7OSJjbBr8 gl2I70LeVNGEXZsAThUkqj5Rg9bV8xw3aSMCMQCDjB5CgsLH8EdZmiksdBRRKM2r vxo6c0dSSNrr7dDN+m2/dRvgoIpGL2GauOGqDFY= -----END CERTIFICATE----- ``` **Freebox Root CA** ```lua -----BEGIN CERTIFICATE----- MIIFmjCCA4KgAwIBAgIJAKLyz15lYOrYMA0GCSqGSIb3DQEBCwUAMFoxCzAJBgNV BAYTAkZSMQ8wDQYDVQQIDAZGcmFuY2UxDjAMBgNVBAcMBVBhcmlzMRAwDgYDVQQK DAdGcmVlYm94MRgwFgYDVQQDDA9GcmVlYm94IFJvb3QgQ0EwHhcNMTUwNzMwMTUw OTIwWhcNMzUwNzI1MTUwOTIwWjBaMQswCQYDVQQGEwJGUjEPMA0GA1UECAwGRnJh bmNlMQ4wDAYDVQQHDAVQYXJpczEQMA4GA1UECgwHRnJlZWJveDEYMBYGA1UEAwwP RnJlZWJveCBSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA xqYIvq8538SH6BJ99jDlOPoyDBrlwKEp879oYplicTC2/p0X66R/ft0en1uSQadC sL/JTyfgyJAgI1Dq2Y5EYVT/7G6GBtVH6Bxa713mM+I/v0JlTGFalgMqamMuIRDQ tdyvqEIs8DcfGB/1l2A8UhKOFbHQsMcigxOe9ZodMhtVNn0mUyG+9Zgu1e/YMhsS iG4Kqap6TGtk80yruS1mMWVSgLOq9F5BGD4rlNlWLo0C3R10mFCpqvsFU+g4kYoA dTxaIpi1pgng3CGLE0FXgwstJz8RBaZObYEslEYKDzmer5zrU1pVHiwkjsgwbnuy WtM1Xry3Jxc7N/i1rxFmN/4l/Tcb1F7x4yVZmrzbQVptKSmyTEvPvpzqzdxVWuYi qIFSe/njl8dX9v5hjbMo4CeLuXIRE4nSq2A7GBm4j9Zb6/l2WIBpnCKtwUVlroKw NBgB6zHg5WI9nWGuy3ozpP4zyxqXhaTgrQcDDIG/SQS1GOXKGdkCcSa+VkJ0jTf5 od7PxBn9/TuN0yYdgQK3YDjD9F9+CLp8QZK1bnPdVGywPfL1iztngF9J6JohTyL/ VMvpWfS/X6R4Y3p8/eSio4BNuPvm9r0xp6IMpW92V8SYL0N6TQQxzZYgkLV7TbQI Hw6v64yMbbF0YS9VjS0sFpZcFERVQiodRu7nYNC1jy8CAwEAAaNjMGEwHQYDVR0O BBYEFD2erMkECujilR0BuER09FdsYIebMB8GA1UdIwQYMBaAFD2erMkECujilR0B uER09FdsYIebMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqG SIb3DQEBCwUAA4ICAQAZ2Nx8mWIWckNY8X2t/ymmCbcKxGw8Hn3BfTDcUWQ7GLRf MGzTqxGSLBQ5tENaclbtTpNrqPv2k6LY0VjfrKoTSS8JfXkm6+FUtyXpsGK8MrLL hZ/YdADTfbbWOjjD0VaPUoglvo2N4n7rOuRxVYIij11fL/wl3OUZ7GHLgL3qXSz0 +RGW+1oZo8HQ7pb6RwLfv42Gf+2gyNBckM7VVh9R19UkLCsHFqhFBbUmqwJgNA2/ 3twgV6Y26qlyHXXODUfV3arLCwFoNB+IIrde1E/JoOry9oKvF8DZTo/Qm6o2KsdZ dxs/YcIUsCvKX8WCKtH6la/kFCUcXIb8f1u+Y4pjj3PBmKI/1+Rs9GqB0kt1otyx Q6bqxqBSgsrkuhCfRxwjbfBgmXjIZ/a4muY5uMI0gbl9zbMFEJHDojhH6TUB5qd0 JJlI61gldaT5Ci1aLbvVcJtdeGhElf7pOE9JrXINpP3NOJJaUSueAvxyj/WWoo0v 4KO7njox8F6jCHALNDLdTsX0FTGmUZ/s/QfJry3VNwyjCyWDy1ra4KWoqt6U7SzM d5jENIZChM8TnDXJzqc+mu00cI3icn9bV9flYCXLTIsprB21wVSMh0XeBGylKxeB S27oDfFq04XSox7JM9HdTt2hLK96x1T7FpFrBTnALzb7vHv9MhXqAT90fPR/8A== -----END CERTIFICATE----- ``` If you want your app to work in Italy, in addition to changing the default domain, you should trust this ECC Root CA: ```lua -----BEGIN CERTIFICATE----- MIICOjCCAcCgAwIBAgIUI0Tu7zsrBJACQIZgLMJobtbdNn4wCgYIKoZIzj0EAwIw TDELMAkGA1UEBhMCSVQxDjAMBgNVBAgMBUl0YWx5MQ4wDAYDVQQKDAVJbGlhZDEd MBsGA1UEAwwUSWxpYWRib3ggRUNDIFJvb3QgQ0EwHhcNMjAxMTI3MDkzODEzWhcN NDAxMTIyMDkzODEzWjBMMQswCQYDVQQGEwJJVDEOMAwGA1UECAwFSXRhbHkxDjAM BgNVBAoMBUlsaWFkMR0wGwYDVQQDDBRJbGlhZGJveCBFQ0MgUm9vdCBDQTB2MBAG ByqGSM49AgEGBSuBBAAiA2IABMryJyb2loHNAioY8IztN5MI3UgbVHVP/vZwcnre ZvJOyDvE4HJgIti5qmfswlnMzpNbwf/MkT+7HAU8jJoTorRm1wtAnQ9cWD3Ebv79 RPwtjjy3Bza3SgdVxmd6fWPUKaNjMGEwHQYDVR0OBBYEFDUij/4lpoJ+kOXRyrcM jf2RPzOqMB8GA1UdIwQYMBaAFDUij/4lpoJ+kOXRyrcMjf2RPzOqMA8GA1UdEwEB /wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQC6eUV1 pFh4UpJOTc1JToztN4ttnQR6rIzxMZ6mNCe+nhjkohWp24pr7BpUYSbEizYCMAQ6 LCiBKV2j7QQGy7N1aBmdur17ZepYzR1YV0eI+Kd978aZggsmhjXENQYVTmm/XA== -----END CERTIFICATE----- ``` and this RSA Root CA: ```lua -----BEGIN CERTIFICATE----- MIIFiTCCA3GgAwIBAgIUTXoJE/kJnSKpxk5FjcmqmGah9zcwDQYJKoZIhvcNAQEL BQAwTDELMAkGA1UEBhMCSVQxDjAMBgNVBAgMBUl0YWx5MQ4wDAYDVQQKDAVJbGlh ZDEdMBsGA1UEAwwUSWxpYWRib3ggUlNBIFJvb3QgQ0EwHhcNMjAxMTI3MDkzODEy WhcNNDAxMTIyMDkzODEyWjBMMQswCQYDVQQGEwJJVDEOMAwGA1UECAwFSXRhbHkx DjAMBgNVBAoMBUlsaWFkMR0wGwYDVQQDDBRJbGlhZGJveCBSU0EgUm9vdCBDQTCC AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANXKZSyCmix6jt7jUmaCP4XF caF4azeYZuA8A4sWQmQXRWTDj8oNClE5w7zo5qUYzHIBOubKY7hhIU7RXYR5Bdny arNRoo5ZBplgEkv3G00IgXY2/lCywPQ8WorAn0k/uaRce239r6EkGC3fxCA3Asnc q9lNkUoWaf0GktJai0DuW7bNY8cq+vzZpy/36ey0LQ4OoehfiA6vlUTVWakpjecJ ller1RfVlgEH26wnerGge3LYBZv27XiahCft54AQLxRY3H/z8XpKsPnJJrrhEvSo 2p64Bd+g7ZbzCdeakrypjVC/eWn14UzbcBVgh0p4F4990LuGxLVqyh6XcZOSSi01 4fpca5xPDCiohEX7ehMLpdURbhKzPj17IpwTmonfVmxkvV8rca1PqhDPEOouwPtc M55eCgtwgSBeDznFKD7s+az/SZYC16GTgyXTCd2lId/J1unZ4pdzNVMAglTpnGgz eQkHvfcVYdJj49tOtW0OpSPBiNIC6LCVY9wtH5dRMm0k+A8QDP+9HQaOs3LIUMwu WGePw6r+eXUYw/2yO0z3zI/63hOpzZVixW+T7h3SY5B+sTrxR9fRD1oyk/rPV4I3 X5mZnyzSowjcN3+hSkGIZBleMO3CHaYleIf1/9HHhCJCVeeJ4kwEWY18Z0A+ohFh D/dipgwmLCDH1/irDT4pAgMBAAGjYzBhMB0GA1UdDgQWBBTcW1RrTVIizaqkrkTI CSw86qDJkTAfBgNVHSMEGDAWgBTcW1RrTVIizaqkrkTICSw86qDJkTAPBgNVHRMB Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAOfi6 fCuVLJD+vttO34cdB3i5hofmNrzgLh/spnwdm4y9EvvVqDvLdVLEIbvKf0QEcW0Y dwP1BgmKwwHVv9YydHov8Jr4ANoGGXJnPLPcYDhRnixYEQmlTwSL/CLUcQ2hQWXx Oc0k1jJB7uk6TPdX2YJyW4NpIcwI2sa5Dg/L8PqM0/pMYnMyG1hBwUc2M2qg3qTJ zeiYT9zBHxS/JXA40yH4g9NzcFisVuYrfmINb11GmeqClm2OWehSdgdv9tEph3NW ntJTENRrDvuj/pGZsnbofzgHNN6/nanymmrEPxG+xUGLIAW7zFndTKityhJ9FRqF ultoZR2D19hh+n1277TSCPRJzUpq9rrfiqukjua3UjBzEvevnmSbLs1bXcNAxFYN oZZ2euHoBv+E3BHjGik4RUkEJYtf5Xh+iffk4zTMfKBERn40fB7yF1xzxyoziltL VxfueF9V6N7qjo5Ia7kiShXXsB+QdQdweuxWm1pPYmMbfTxNEqFUs3GhwEjzLaJc cJOedwCT4ntbyCcTQaRlDL8QFjdE4gNm2ZaoG+gqGTLPS55H+ZvLsgUCiR5YY44N G2Gkv4w/V/eB3eAvd5lgm6oOe8ehdr5JdpD6wnW2GOHs4SBdBo6yR+4RgEimNmgF Yu11tlZsB2Iw/TT1EyPVb5z6tK4wUgWLNFAvjXU= -----END CERTIFICATE----- ``` ## Authentication Unless otherwise stated API access must be authenticated using the procedure described in the following document ### Login Each application identified with an *app_name* must gain access to Freebox API before being able to use the api. This procedure can only be initiated from the local network, and the user must have access to the Freebox front panel to grant access to the app. Note that since you must be on the local network, you must do your requests on https://mafreebox.freebox.fr for the initial app authorization, since adding a new app is forbidden from the outside network, and then use the generated [api_domain]:[freebox_port] for subsequent accesses. Once the user authorize the app, the app will be provided with a unique *app_token* associated with a set of default permissions. This *app_token* must be store securely by the app, and will not be exchanged in clear text for the following requests. Note that the user can revoke the *app_token*, or edit its permissions afterwards. For instance if the user resets the admin password, app permissions will be reset. Then the app will need to open a *session* to get an *auth_token*. The app will then be authenticated by adding this session_token in HTTP headers of the following requests. The validity of the *auth_token* is limited in time and the app will have to renew this *auth_token* once in a while. #### Obtaining an *app_token* ##### TokenRequest object TokenRequest objects have the following attributes ###### Object `TokenRequest` | Property | Type | Access | Description | | --- | --- | --- | --- | | `app_id` | string | | A unique app_id string | | `app_name` | string | | A descriptive application name (will be displayed on lcd) | | `app_version` | string | | app version | | `device_name` | string | | The name of the device on which the app will be used | ##### Request authorization This is the first step, the app will ask for an *app_token* using the following call. A message will be displayed on the Freebox LCD asking the user to grant/deny access to the requesting app. Once the app has obtained a valid app_token, it will not have to do this procedure again unless the user revokes the app_token. ###### `POST /login/authorize/` *no session required* Request body (`application/json`): TokenRequest Response `result`: { app_token: string, track_id: integer } Example request: ```http POST /api/v{version}/login/authorize/ HTTP/1.1 Host: mafreebox.freebox.fr { "app_id": "fr.freebox.testapp", "app_name": "Test App", "app_version": "0.0.7", "device_name": "Pc de Xavier" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "app_token": "dyNYgfK0Ya6FWGqq83sBHa7TwzWo+pg4fDFUJHShcjVYzTfaRrZzm93p7OTAfH/0", "track_id": 42 } } ``` ##### Track authorization progress Once the authorization request has been made, the app should monitor the token status by using the following API and using the *track_id* returned by the previous call. The status can have one of the following values: | Status | Description | | --- | --- | | unknown | the app_token is invalid or has been revoked | | pending | the user has not confirmed the authorization request yet | | timeout | the user did not confirmed the authorization within the given time | | granted | the app_token is valid and can be used to open a session | | denied | the user denied the authorization request | The app should monitor the status until it is different from pending. You MUST implement this monitoring, otherwise your authorization will be invalid, even if the user grants you access. ###### `GET /login/authorize/{track_id}` *no session required* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `track_id` | path | integer | | Response `result`: { status: string, challenge: string } Example request: ```http GET /api/v{version}/login/authorize/42 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "status": "pending", "challenge": "Bj6xMqoe+DCHD44KqBljJ579seOXNWr2" } } ``` Example response once the user has validated the request: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "status": "granted", "challenge": "Bj6xMqoe+DCHD44KqBljJ579seOXNWr2" } } ``` #### Obtaining a *session_token* To protect the *app_token* secret, it will never be used directly to authenticate the application, instead the API will provide a challenge the app will combine to its *app_token* to open a session and get a *session_token* The app will then have to include the *session_token* in the HTTP headers of the following requests ##### SessionStart object SessionStart objects have the following attributes: ###### Object `SessionStart` | Property | Type | Access | Description | | --- | --- | --- | --- | | `app_id` | string | | Same app_id used in TokenRequest to get the app_token | | `app_version` | string | | app version | | `password` | string | | The password computed using the challenge and the app_token To compute the password you have to compute the hmac-sha1 of the challenge and the app_token password = hmac-sha1(app_token, challenge) | ##### Getting the challenge value The challenge returned by the API will change frequently and have a limited time validity. There are several ways of getting the current challenge value, it will always be included in response requesting the app authentication. It is also included in the authorization tracking API response. You can also explicitly request a challenge with the following API ###### `GET /login/` *no session required* Response `result`: { logged_in: boolean, challenge: string } Example request: ```http GET /api/v{version}/login/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "logged_in": false, "challenge": "VzhbtpR4r8CLaJle2QgJBEkyd8JPb0zL" } } ``` ##### Opening a session Once you have the challenge you just need use the following API to get a *session_token* NOTE: in case of session opening failure, ensure that the box you’re connected is the one you expect by checking the uid returned in the answer. In the response you get your app permissions. App permissions are: | App permission | Description | | --- | --- | | settings | Allow modifying the Freebox settings (reading settings is always allowed) | | contacts | Access to contact list | | calls | Access to call logs | | explorer | Access to filesystem | | downloader | Access to downloader | | parental | Access to parental control (obsolete) | | pvr | Access personal video recorder | | profile | Access to user profile management | NOTE: A permission not listed in app permissions is equivalent to having this permission set to false. NOTE: There is no “privileged read” for the “settings” permission. This means that, by default, any allowed application can read sensitive information, such as MAC addresses, even without the “settings” permission. Certain items, such as Wi-Fi or VPN credentials, are therefore denied or obfuscated if you do not have full access. ###### `POST /login/session/` *no session required* Request body (`application/json`): { app_id: string, password: string } Response `result`: { session_token: string, challenge: string, permissions: { downloader: boolean } } Example request: ```http POST /api/v{version}/login/session/ HTTP/1.1 Host: mafreebox.freebox.fr { "app_id": "fr.freebox.testapp", "password": "d4da8517c2c25b1b145f2e5ba91bd0589fc0053d" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "session_token": "35JYdQSvkcBYK84IFMU7H86clfhS75OzwlQrKlQN1gBch/Dd62RGzDpgC7YB9jB2", "challenge": "jdGL6CtuJ3Dm7p9nkcIQ8pjB+eLwr4Ya", "permissions": { "downloader": true } } } ``` Example response with invalid password: ```http HTTP/1.1 403 Forbidden Content-Type: application/json; charset=utf-8 ``` ```json { "msg": "Erreur d'authentification de l'application", "success": false, "uid": "23b86ec8091013d668829fe12791fdab", "error_code": "invalid_token", "result": { "challenge": "DLjXFEf1kaDwAEn6xRUnEVPU++gnjiSn" } } ``` #### Closing the current session to close the current session you can use the following call ##### `POST /login/logout/` Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http POST /api/v{version}/login/logout/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` #### Make an authenticated call to the API Once you have a valid *session_token* you should use it by add the the HTTP header **X-Fbx-App-Auth** **Example request**: ```http GET /api/v{version}/login/session/ HTTP/1.1 Host: mafreebox.freebox.fr X-Fbx-App-Auth: 35JYdQSvkcBYK84IFMU7H86clfhS75OzwlQrKlQN1gBch\/Dd62RGzDpgC7YB9jB2 ``` **Example response**: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": {} } ``` ##### Authentication errors When attempting to access the API, you may encounter the following authentication errors: NOTE that in this case the HTTP 403 return code will be used as well | Error | Description | | --- | --- | | auth_required | Invalid session token, or not session token sent | | invalid_token | The app token you are trying to use is invalid or has been revoked | | pending_token | The app token you are trying to use has not been validated by user yet | | insufficient_rights | Your app permissions does not allow accessing this API | | denied_from_external_ip | You are trying to get an app_token from a remote IP | | invalid_request | Your request is invalid | | ratelimited | Too many auth error have been made from your IP | | new_apps_denied | New application token request has been disabled | | apps_denied | API access from apps has been disabled | | internal_error | Internal error | ## WebSocket API WebSocket allow bidirectional communication between your api client and the Freebox. This allow more interactivity without the need of frequently polling data from the Freebox. For WebSocket access, you must use the same Authentication mechanism as for regular http api request. This means that you must include a proper **X-Fbx-App-Auth** header when you open the WebSocket connection. Once the connection is established, most of messages sent via the WebSocket are text based (using utf-8 as per WebSocket specifications) and encoded as JSON objects. The WebSocket frames maximum accepted size is 1 MB ### WebSocket API conventions As for HTTP api, the client can make requests to the Freebox (the available requests are specified per api). The requests use the following format: #### Object `WebSocketRequest` | Property | Type | Access | Description | | --- | --- | --- | --- | | `request_id` | integer | | if you specify a request_id in your request, it will be added in the corresponding reply, so that you can correlate responses to the request | | `action` | string | | the request ‘action’ (available actions are described in each api) | Other fields, related to a specific action, will be used as ‘action’ parameters Responses to such requests will have the following format: #### Object `WebSocketResponse` | Property | Type | Access | Description | | --- | --- | --- | --- | | `request_id` | integer | | if you set a request_id in your WebSocketRequest, the same request_id will be returned in the associated response | | `action` | string | | the action specified in the associated WebSocketRequest | | `success` | boolean | read-only | indicates if the request was successful | | `result` | object | read-only | the result of the request. (It may be omitted if the request does not expect any result) | | `error_code` | string | read-only | In case of request error, this error_code provides information about the error. The possible error_code values are documented for each API. | | `msg` | string | read-only | In cas of error, provides a French error message relative to the error | When the Freebox wants to send a notification on WebSocket it will have the following format: #### Object `WebSocketNotification` | Property | Type | Access | Description | | --- | --- | --- | --- | | `action` | string | read-only | The action will have the value ‘notification’ | | `success` | boolean | read-only | will be True | | `source` | string | read-only | The name of the source of the notification | | `event` | string | read-only | The name of event that generated the notification | | `result` | object | read-only | the content of the notification (may be omitted if no data has to be transferred along with the notification) | ### WebSocket event API This API is used to send events to an application, removing the need to poll when waiting for a long operation to complete. It follows the conventions of the WebSocket API. This is a text websocket that sends json, one per line. #### `GET /ws/event` *WebSocket upgrade* The application sends RegisterACtion to subscribe to an event channel. It will subsequently receive events on this websocket. Response: `101 Switching Protocols`. #### Register Action ##### Object `RegisterAction` | Property | Type | Access | Description | | --- | --- | --- | --- | | `action` | string | | Value should be “register” | | `events` | string[] | | List of events to subscribe for. Possible values: Item values: `vm_state_changed` (VmStateChange VM status has changed), `vm_disk_task_done` (VmDiskTask VM disk task done), `lan_host_l3addr_reachable` (LanHost LAN machine had an L3 address (IPv4 or IPv6) become reachable. Usually when a machine appears on the network, or changes IP.), `lan_host_l3addr_unreachable` (LanHost LAN machine had an L3 address (IPv4 or IPv6) become unreachable. Usually when a machine disappears from the network (after a timeout), or changes IP.). | Response is usually `{"success": true, "action": "register"}` Events will be sent as `WebSocketNotification` ; the event name will be split in source (prefix) and event (suffix). For example, vm_disk_task_done will have source “vm”, and event “disk_task_done”: ```json { "action": "notification", "success": true, "source": "vm", "event": "disk_task_done", "result": { "done": true, "error": false, "id": 1 } } ``` ## Air Media ### AirMedia API This API allows you to multimedia stream to any airmedia device reachable by the Freebox, as well as configuring the airmedia server hosted on the Freebox Server. #### AirMedia Errors When attempting to access the file airmedia API, you may encounter the following errors: | error_code | Description | | --- | --- | | unknown_target | No airmedia device with this name in range | | no_client | No airmedia client connected | | set_pass | Unable to update password | | set_onscreen_code | Unable to activate onscreen code | | no_ctrl | Remote control is unavailable | | http | Internal HTTP error | | bad_session | No stream session found | | bad_name | Invalid airmedia name | | bad_device_id | No device with this id | | bad_remote_id | No remote control with this id | | req_in_progress | You should try again, another request is still processing | | fetch | Unable to get slideshow information | | no_display | No screen available | | playback_state | Invalid playback state | | no_slideshow_srv | Slideshow is not supported | | no_mem | Internal error | | inout_file | Unable to read input file | | no_volume_control | Volume control is not available | | connect | Error connecting to the airmedia device | | unauthorized | This device requests a password | | unsupported_media | The device does not support this format | | bad_type | Invalid file type | | unimplemented | Unimplemented | #### AirMedia Config Object AirMedia config has the following attributes: ##### Object `AirMediaConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `enabled` | boolean | | Enable/Disable the airmedia server | | `password` | string | write-only | If not empty, the client will have to enter a password to be able to use this airmedia server | #### AirMedia Configuration API ##### Get the current AirMedia configuration ###### `GET /airmedia/config/` Returns the current AirMediaConfig Response `result`: AirMediaConfig Example request: ```http GET /api/v{version}/airmedia/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": true } } ``` ##### Update the current AirMedia configuration ###### `PUT /airmedia/config/` Update the current AirMediaConfig Request body (`application/json`): AirMediaConfig Response `result`: AirMediaConfig Example request: *The documentation example uses `PUT /airmedia/`, which differs from the operation path.* ```http PUT /api/v{version}/airmedia/ HTTP/1.1 Host: mafreebox.freebox.fr { "enabled": true, "password": "3615" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": true } } ``` #### AirMedia Receiver Object AirMedia receivers have the following attributes ##### Object `AirMediaReceiver` | Property | Type | Access | Description | | --- | --- | --- | --- | | `name` | string | read-only | AirMedia name | | `password_protected` | boolean | read-only | Is set to true the receiver is protected by a password | | `capabilities` | object | read-only | List of receiver capabilities from the following list Documented values: `photo` (can display photos), `audio` (can play audio files), `video` (can play video files), `screen` (can display remote screen). | ##### Get the list of available AirMedia receivers You can get the list of `AirMediaReceiver` connected to the Freebox Server using this API ###### `GET /airmedia/receivers/` Get the list of AirMediaReceiver connected to the Freebox Server Response `result`: AirMediaReceiver[] Example request: ```http GET /api/v{version}/airmedia/receivers/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "capabilities": { "photo": true, "screen": false, "audio": true, "video": true }, "name": "Freebox Player", "password_protected": true }, { "capabilities": { "photo": false, "screen": false, "audio": true, "video": false }, "name": "Freebox Server", "password_protected": false } ] } ``` ##### Interacting with an AirMedia receiver Once you have selected an available `AirMediaReceiver` you can start interacting with it by sending media with the following API. ###### AirMedia receiver request ###### Object `AirMediaReceiverRequest` | Property | Type | Access | Description | | --- | --- | --- | --- | | `action` | string | | Values: `start` (start playing a media), `stop` (stop playing a media). | | `media_type` | string | | Documented values: `photo` (display a photo), `video` (display a video). | | `password` | string | | Optional receiver password. | | `position` | integer | | Start position for a video. The start position is expressed in percent * 1000, for instance 50000 means 50% of the video | | `media` | string | | The media to play. For video media, you have to specify the media URL, for instance http://anon.nasa-global.edgesuite.net/HD_downloads/GRAIL_launch_480.mov For photo media, you have to specify the file path on the Freebox Server (base64 encoded as returned in fs/ls call), for instance L0Rpc3F1ZSBkdXIvUGhvdG9zL1JvY2tldHMvRFNDXzM0OTEuanBn | ###### Sending a new request to an AirMedia receiver ###### `POST /airmedia/receviers/{receiver_name}/` Example: display a photo on the Freebox Player: Example: play a video the Freebox Player: Example: stop the current AirMedia video on Freebox Player: | Parameter | In | Type | Description | | --- | --- | --- | --- | | `receiver_name` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). ```http POST /api/v{version}/airmedia/receivers/Freebox%20Player/ HTTP/1.1 Host: mafreebox.freebox.fr { "action": "start", "media_type": "photo", "media": "L0Rpc3F1ZSBkdXIvUGhvdG9zL1JvY2tldHMvRFNDXzM0OTEuanBn", "password": "1111" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ```http POST /api/v{version}/airmedia/receivers/Freebox%20Player/ HTTP/1.1 Host: mafreebox.freebox.fr { "action": "start", "media_type": "video", "media": "http://anon.nasa-global.edgesuite.net/HD_downloads/GRAIL_launch_480.mov", "password": "1111" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ```http POST /api/v{version}/airmedia/receivers/Freebox%20Player/ HTTP/1.1 Host: mafreebox.freebox.fr { "action": "stop", "media_type": "video" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ## Calls / Contacts ### Call With the call API you access the Freebox call logs. #### Call Errors When attempting to access the call API, you may encounter the following errors: | error_code | Description | | --- | --- | | internal_error | Internal error | | invalid_id | No call with this id | | invalid_category | Invalid call category | #### Call Object Call entries have the following properties ##### Object `CallEntry` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | read-only | id | | `type` | string | read-only | The valid call types are: Values: `missed` (Missed incoming call), `accepted` (Incoming call), `outgoing` (Outgoing call). | | `datetime` | integer (unix-time) | read-only | UNIX timestamp (seconds) Call creation timestamp. | | `number` | string | read-only | Callee number for outgoing calls. Caller number for incoming calls. | | `name` | string | read-only | Callee name for outgoing calls. Caller name for incoming calls. For incoming call if the network does not provide a contact name, we try to use the contact database to find a suitable name | | `duration` | integer | read-only | Call duration in seconds. | | `new` | boolean | | Call entry has not been acknowledged yet. | | `contact_id` | integer | read-only | If the number matches an entry in the contact database, the id of the matching contact. | #### Call API This is the call API ##### List every calls ###### `GET /call/log/` *permission `calls` (inferred)* Returns the collection of all CallEntry call entries Response `result`: CallEntry[] Example request: ```http GET /api/v{version}/call/log/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "number": "0102030405", "type": "missed", "id": 69, "duration": 1, "datetime": 1359546363, "contact_id": 56, "line_id": 0, "name": "r0ro (Freebox)", "new": true }, { "number": "**1", "type": "outgoing", "id": 68, "duration": 5, "datetime": 1359545960, "contact_id": 0, "line_id": 0, "name": "**1", "new": false } ] } ``` ##### Delete all calls ###### `POST /call/log/delete_all/` *permission `calls` (inferred)* Remove all CallEntry call entries Response `result`: CallEntry Example request: *The documentation example uses `GET /call/log/delete_all`, which differs from the operation path.* ```http GET /api/v{version}/call/log/delete_all HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ##### Mark all calls as read ###### `POST /call/log/mark_all_as_read/` *permission `calls` (inferred)* Mark all CallEntry call entries as read Response `result`: CallEntry Example request: *The documentation example uses `GET /call/log/mark_all_as_read`, which differs from the operation path.* ```http GET /api/v{version}/call/log/mark_all_as_read HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ##### Access a given call entry ###### `GET /call/log/{id}` *permission `calls` (inferred)* Returns the CallEntry task with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: CallEntry Example request: ```http GET /api/v{version}/call/log/69 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "number": "0102030405", "type": "missed", "id": 69, "duration": 1, "datetime": 1359546363, "contact_id": 56, "line_id": 0, "name": "Romain Bureau", "new": true } } ``` ##### Delete a call ###### `DELETE /call/log/{id}` *permission `calls` (inferred)* Deletes the CallEntry with the given id. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/call/log/69 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Update a call entry ###### `PUT /call/log/{id}` *permission `calls` (inferred)* Updates the CallEntry task with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Request body (`application/json`): CallEntry Response `result`: CallEntry Example request: ```http PUT /api/v{version}/call/log/69 HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "new": "false" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "number": "0102030405", "type": "missed", "id": 69, "duration": 1, "datetime": 1359546363, "contact_id": 56, "line_id": 0, "name": "Romain Bureau", "new": false } } ``` ### Account The account API returns the phone number associated with the subscription. #### `GET /call/account` *permission `calls` (inferred)* Returns an object containing the phone number associated with the subscription. Response `result`: { phone_number: string } Example request: ```http GET /api/v{version}/call/account/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "phone_number": "0999999999" } } ``` ### Voicemail The voicemail API lets one access voicemail messages. #### Voicemail Errors The following errors may be encountered with the voicemail API: | error_code | Description | | --- | --- | | internal_error | Internal error | | invalid_id | No voicemail with this id | #### Voicemail Object Voicemail entries have the following properties ##### Object `VoicemailEntry` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | string | read-only | id | | `country_code` | string | read-only | Country code part of the caller number. May be empty. | | `phone_number` | string | read-only | Caller number. May be empty. | | `date` | integer (unix-time) | read-only | UNIX timestamp (seconds) Voicemail creation timestamp. | | `read` | boolean | | Voicemail read status | | `duration` | integer | read-only | Voicemail duration in seconds | #### Voicemail API ##### List voicemails ###### `GET /call/voicemail/` *permission `calls` (inferred)* Returns a collection of all VoicemailEntry voicemail entries Response `result`: VoicemailEntry[] Example request: ```http GET /api/v{version}/call/voicemail/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "phone_number": "699999999", "read": false, "id": "20221215_154135_r0334371508.au", "duration": 8, "country_code": 33, "date": 1671115295 } ] } ``` ##### Access a specific voicemail entry ###### `GET /call/voicemail/{id}` *permission `calls` (inferred)* Returns the VoicemailEntry task with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response `result`: VoicemailEntry Example request: ```http GET /api/v{version}/call/voicemail/20221215_154135_r0334371508.au HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "phone_number": "699999999", "read": false, "id": "20221215_154135_r0334371508.au", "duration": 8, "country_code": 33, "date": 1671115295 } } ``` ##### Delete a voicemail ###### `DELETE /call/voicemail/{id}` *permission `calls` (inferred)* Deletes the VoicemailEntry with the given id. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/call/voicemail/20221215_154135_r0334371508.au HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Update a voicemail entry ###### `PUT /call/voicemail/{id}` *permission `calls` (inferred)* Updates the VoicemailEntry with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Request body (`application/json`): VoicemailEntry Response `result`: VoicemailEntry Example request: ```http PUT /api/v{version}/call/voicemail/20221215_154135_r0334371508.au HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "phone_number": "699999999", "read": true, "id": "20221215_154135_r0334371508.au", "duration": 8, "country_code": 33, "date": 1671115295 } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "phone_number": "699999999", "read": true, "id": "20221215_154135_r0334371508.au", "duration": 8, "country_code": 33, "date": 1671115295 } } ``` ##### Retrieve a voicemail ###### `GET /call/voicemail/{id}/audio_file` *permission `calls` (inferred)* Download voicemail message in WAV format. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: `audio/wav` Example request: ```http GET /api/v{version}/call/voicemail/20221215_154135_r0334371508.au/audio_file HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: audio/wav; charset=utf-8 Content-Length: 60218 Content-Disposition: inline; filename="20221215_154135_r0334371508.wav" /* binary data */ ``` ### Contacts The contact API allow to interact with the contact list stored on the Freebox #### Contacts Errors When attempting to access the contact API, you may encounter the following errors: | error_code | Description | | --- | --- | | noent | no entry with this id | | exists | an entry already exists | | no_match | no entry matched your request | #### Contact Objects ##### Contact Entry Contact entries have the following properties ###### Object `ContactEntry` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | | contact id | | `display_name` | string | | contact display name | | `first_name` | string | | contact first name | | `last_name` | string | | contact last name | | `company` | string | | contact company name | | `photo_url` | string | | contact photo URL NOTE the photo URL can be embedded (for instance “data:image/jpeg;base64,/9j/4AA [ … ]”) | | `last_update` | integer (unix-time) | | UNIX timestamp (seconds) contact last modification timestamp | | `notes` | string | | contact last modification timestamp | | `addresses` | ContactAddress[] | | list of contact postal addresses | | `emails` | ContactEmail[] | | list of contact email addresses | | `numbers` | ContactNumber[] | | list of contact phone numbers | | `urls` | ContactUrl[] | | list of contact URL | ##### Contact Number Contact number have the following properties ###### Object `ContactNumber` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | | address id | | `contact_id` | integer | | id of the related contact | | `type` | string | | Type of number Values: `fixed` (fixed phone), `mobile` (mobile phone), `work` (work), `fax` (fax), `other` (other). | | `number` | string | | | | `is_default` | boolean | | is this number the preferred contact phone number | | `is_own` | boolean | | is this number the Freebox owner number | ##### Contact Address Contact address have the following properties ###### Object `ContactAddress` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | | address id | | `contact_id` | integer | | id of the related contact | | `type` | string | | Type of email Values: `home` (home address), `work` (work address), `other` (other). | | `number` | string | | | | `street` | string | | | | `street2` | string | | | | `city` | string | | | | `zipcode` | string | | | | `country` | string | | | ##### Contact Url Contact URL have the following properties ###### Object `ContactUrl` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | | address id | | `contact_id` | integer | | id of the related contact | | `type` | string | | Type of URL Values: `profile` (profile address), `blog` (blog address), `site` (website address), `other` (other). | | `url` | string | | URL address | ##### Contact Email Contact email have the following properties ###### Object `ContactEmail` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | | address id | | `contact_id` | integer | | id of the related contact | | `type` | string | | Type of address Values: `home` (home address), `work` (work address), `other` (other). | | `email` | string | | email address | #### Contact API ##### Get a list of contacts ###### `GET /contact/` *permission `contacts` (inferred)* Returns the collection of all ContactEntry | Parameter | In | Type | Description | | --- | --- | --- | --- | | `start` (optional) | query | integer | Offset | | `limit` (optional) | query | integer | Limit of contact to return (-1 means no limit) | | `group_id` (optional) | query | integer | Return only the contacts that belong to this group | Response `result`: ContactEntry[] Example request: ```http GET /api/v{version}/contact/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "last_name": "Niel", "company": "Free", "photo_url": "data:image/jpeg;base64,/9j/4AA [ ... ]", "id": 2, "birthday": "", "last_update": 1363964483, "display_name": "", "emails": [ { "id": 2, "contact_id": 2, "type": "home", "email": "rocket@launchpad.free" } ], "urls": [ { "id": 1, "contact_id": 2, "url": "http://www.free.fr/", "type": "site" } ], "notes": "", "first_name": "Xavier" }, { "last_name": "Mamie", "first_name": "Kipic", "company": "", "photo_url": "data:image/jpeg;base64,/9j/4A [ ... ] ", "id": 1, "birthday": "", "numbers": [ { "number": "0612345678", "type": "fixed", "id": 1, "contact_id": 1, "is_default": false, "is_own": false } ], "last_update": 1363973599, "display_name": "Mamie", "emails": [ { "id": 1, "contact_id": 1, "type": "home", "email": "mamie@example.org" } ], "urls": [ { "id": 3, "contact_id": 1, "url": "ftp://free.fr", "type": "site" } ], "addresses": [ { "street2": "", "type": "home", "country": "France", "id": 1, "street": "8 rue du pont", "contact_id": 1, "city": "Paris", "zipcode": "75008", "number": "11" } ], "notes": "" } ] } ``` ##### Access a given contact entry ###### `GET /contact/{id}` *permission `contacts` (inferred)* Returns the ContactEntry with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: ContactEntry Example request: ```http GET /api/v{version}/contact/1 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "last_name": "Mamie", "first_name": "Kipic", "company": "", "photo_url": "data:image/jpeg;base64,/9j/4A [ ... ] ", "id": 1, "birthday": "", "numbers": [ { "number": "0612345678", "type": "fixed", "id": 1, "contact_id": 1, "is_default": false, "is_own": false } ], "last_update": 1363973599, "display_name": "Mamie", "emails": [ { "id": 1, "contact_id": 1, "type": "home", "email": "mamie@example.org" } ], "urls": [ { "id": 3, "contact_id": 1, "url": "ftp://free.fr", "type": "site" } ], "addresses": [ { "street2": "", "type": "home", "country": "France", "id": 1, "street": "8 rue du pont", "contact_id": 1, "city": "Paris", "zipcode": "75008", "number": "11" } ], "notes": "" } } ``` ##### Create a contact ###### `POST /contact/` *permission `contacts` (inferred)* Creates a new ContactEntry Request body (`application/json`): ContactEntry Response `result`: ContactEntry Example request: ```http POST /api/v{version}/contact/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "display_name": "Sandy Kilo", "first_name": "Sandy", "last_name": "Kilo" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "last_name": "Kilo", "company": "", "photo_url": "", "id": 10, "birthday": "", "last_update": 1372433423, "display_name": "Sandy Kilo", "notes": "", "first_name": "Sandy" } } ``` ##### Delete a contact ###### `DELETE /contact/{id}` *permission `contacts` (inferred)* Deletes the ContactEntry with the given id. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/contact/1 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Update a contact entry ###### `PUT /contact/{id}` *permission `contacts` (inferred)* Updates the ContactEntry with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Request body (`application/json`): ContactEntry Response `result`: ContactEntry Example request: ```http PUT /api/v{version}/contact/4 HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "company": "Freebox" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "last_name": "Anderson", "company": "Freebox", "photo_url": "data:image/jpeg;base64,/9j/4AAQ [ ... ]", "id": 4, "birthday": "", "last_update": 1363977825, "display_name": "Thomas A. Anderson", "emails": [ { "id": 3, "contact_id": 4, "type": "home", "email": "neo@matrix.com" } ], "notes": "", "first_name": "Thomas" } } ``` #### Contact Related objects API Contact related entries such as phone numbers, addresses, URLs and emails are all handled the same way. Below we’ll document the numbers API, you can use the same calls with addresses, URL and emails. ##### Get the list of numbers for a given contact ###### `GET /contact/{contact_id}/numbers/` *permission `contacts` (inferred)* Returns the collection of all ContactNumber for a given contact | Parameter | In | Type | Description | | --- | --- | --- | --- | | `contact_id` | path | integer | | Response `result`: ContactNumber[] ###### `GET /contact/{contact_id}/addresses/` *permission `contacts` (inferred)* Returns the collection of all ContactNumber for a given contact | Parameter | In | Type | Description | | --- | --- | --- | --- | | `contact_id` | path | integer | | Response `result`: ContactAddress[] ###### `GET /contact/{contact_id}/urls/` *permission `contacts` (inferred)* Returns the collection of all ContactNumber for a given contact | Parameter | In | Type | Description | | --- | --- | --- | --- | | `contact_id` | path | integer | | Response `result`: ContactUrl[] ###### `GET /contact/{contact_id}/emails/` *permission `contacts` (inferred)* Returns the collection of all ContactNumber for a given contact | Parameter | In | Type | Description | | --- | --- | --- | --- | | `contact_id` | path | integer | | Response `result`: ContactEmail[] Example request: ```http GET /api/v{version}/contact/4/numbers/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "number": "+13374242", "type": "fixed", "id": 6, "contact_id": 4, "is_default": false, "is_own": false }, { "number": "0611223344", "type": "mobile", "id": 5, "contact_id": 4, "is_default": false, "is_own": false } ] } ``` ##### Access a given contact number ###### `GET /number/{id}` *permission `contacts` (inferred)* Returns the ContactNumber with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: ContactNumber ###### `GET /address/{id}` *permission `contacts` (inferred)* Returns the ContactNumber with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: ContactAddress ###### `GET /url/{id}` *permission `contacts` (inferred)* Returns the ContactNumber with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: ContactUrl ###### `GET /email/{id}` *permission `contacts` (inferred)* Returns the ContactNumber with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: ContactEmail Example request: ```http GET /api/v{version}/number/6 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "number": "+13374242", "type": "fixed", "id": 6, "contact_id": 4, "is_default": false, "is_own": false } } ``` ##### Create a contact number ###### `POST /number/` *permission `contacts` (inferred)* Creates the ContactNumber Request body (`application/json`): ContactNumber Response `result`: ContactNumber ###### `POST /address/` *permission `contacts` (inferred)* Creates the ContactNumber Request body (`application/json`): ContactAddress Response `result`: ContactAddress ###### `POST /url/` *permission `contacts` (inferred)* Creates the ContactNumber Request body (`application/json`): ContactUrl Response `result`: ContactUrl ###### `POST /email/` *permission `contacts` (inferred)* Creates the ContactNumber Request body (`application/json`): ContactEmail Response `result`: ContactEmail Example request: ```http POST /api/v{version}/number/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "contact_id": 9, "number": "0144456789", "type": "fixed" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "number": "0144456789", "type": "fixed", "id": 18, "contact_id": 9, "is_default": false, "is_own": false } } ``` ##### Delete a contact number ###### `DELETE /number/{id}` *permission `contacts` (inferred)* Deletes the ContactNumber with the given id. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response: no result schema documented (envelope `{ "success": true }`). ###### `DELETE /address/{id}` *permission `contacts` (inferred)* Deletes the ContactNumber with the given id. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response: no result schema documented (envelope `{ "success": true }`). ###### `DELETE /url/{id}` *permission `contacts` (inferred)* Deletes the ContactNumber with the given id. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response: no result schema documented (envelope `{ "success": true }`). ###### `DELETE /email/{id}` *permission `contacts` (inferred)* Deletes the ContactNumber with the given id. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/number/6 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Update a contact number ###### `PUT /number/{id}` *permission `contacts` (inferred)* Updates the ContactNumber with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Request body (`application/json`): ContactNumber Response `result`: ContactNumber ###### `PUT /address/{id}` *permission `contacts` (inferred)* Updates the ContactNumber with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Request body (`application/json`): ContactAddress Response `result`: ContactAddress ###### `PUT /url/{id}` *permission `contacts` (inferred)* Updates the ContactNumber with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Request body (`application/json`): ContactUrl Response `result`: ContactUrl ###### `PUT /email/{id}` *permission `contacts` (inferred)* Updates the ContactNumber with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Request body (`application/json`): ContactEmail Response `result`: ContactEmail Example request: ```http PUT /api/v{version}/number/5 HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "number": "0655667788", "type": "mobile" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "number": "0655667788", "type": "mobile", "id": 5, "contact_id": 4, "is_default": false, "is_own": false } } ``` ## Configuration ### Connection API This API provides Freebox connection settings information. #### Connection Errors When attempting to access the file connection API, you may encounter the following errors: | error_code | Description | | --- | --- | | inval | invalid request | | nodev | no device found with this name | | noent | no entity found with this name | | netdown | network is down | | busy | device is busy | | invalid_port | invalid port | | insecure_password | the password is too weak to enable remote access | | invalid_provider | invalid ddns provider name | | invalid_next_hop | invalid next hop address (should be a link local address) | #### Connection status ##### Connection status object ###### Object `ConnectionStatus` | Property | Type | Access | Description | | --- | --- | --- | --- | | `state` | string | read-only | Values: `going_up` (connection is initializing), `up` (connection is active), `going_down` (connection is about to become inactive), `down` (connection is inactive). | | `type` | string | read-only | Values: `ethernet` (FTTH/ethernet), `rfc2684` (xDSL (unbundled)), `pppoatm` (xDSL). | | `media` | string | read-only | Values: `ftth` (FTTH), `ethernet` (ethernet), `xdsl` (xDSL), `backup_4g` (Internet Backup). | | `ipv4` | string | read-only | Freebox IPv4 address NOTE: this field is only available when connection state is up | | `ipv6` | string | read-only | Freebox IPv6 address NOTE: this field is only available when connection state is up | | `rate_up` | integer | read-only | current upload rate in byte/s | | `rate_down` | integer | read-only | current download rate in byte/s | | `bandwidth_up` | integer | read-only | available upload bandwidth in bit/s | | `bandwidth_down` | integer | read-only | available download bandwidth in bit/s | | `bytes_up` | integer | read-only | total uploaded bytes since last connection | | `bytes_down` | integer | read-only | total downloaded bytes since last connection | | `ipv4_port_range` | integer[] (max 2) | read-only | Some customers share the same IPv4 and each customer is then assigned a port range. The first value is the first port of the assigned range and the second value is the last port (inclusive). All PortForwardingConfig must use ports in this range to be effective. | ##### Get the current Connection status ###### `GET /connection/` Returns the current ConnectionStatus Response `result`: ConnectionStatus Example request: ```http GET /api/v{version}/connection/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "type": "ethernet", "rate_down": 61, "bytes_up": 5489542, "rate_up": 0, "bandwidth_up": 100000000, "ipv4": "13.37.42.42", "ipv4_port_range": [ 0, 65535 ], "ipv6": "2a01:e30:d252:a2a0::1", "bandwidth_down": 100000000, "state": "up", "bytes_down": 13332830, "media": "ftth" } } ``` #### Connection configuration ##### Connection configuration object ###### Object `ConnectionConfiguration` | Property | Type | Access | Description | | --- | --- | --- | --- | | `ping` | boolean | | should the Freebox respond to external ping requests | | `is_secure_pass` | boolean | read-only | is the admin password secure enough to enable remote access | | `remote_access` | boolean | | enable/disable HTTP remote access | | `remote_access_port` | integer | | port number to use for remote HTTP access | | `remote_access_min_port` | integer | read-only | This field indicate the minimum possible value for remote_access_port (see ConnectionStatus ipv4_port_range) | | `remote_access_max_port` | integer | read-only | This field indicate the maximum possible value for remote_access_port (see ConnectionStatus ipv4_port_range) | | `remote_access_ip` | string | read-only | IPv4 to use for remote access (can be missing if connection is down) | | `api_remote_access` | boolean | read-only | is remote access enabled for apps, or share link | | `wol` | boolean | | enable/disable Wake-on-lan proxy | | `adblock` | boolean | | is ads blocking feature enabled | | `adblock_not_set` | boolean | read-only | if set to true adblock setting has never been set by the user | | `allow_token_request` | boolean | | if false, user has disabled new token request. New apps can’t request a new token. Apps that already have a token are still allowed | | `sip_alg` | string | | Values: `disabled` (Fully disable SIP ALG), `direct_media` (Enable SIP ALG, RTP only allowed between SIP UA), `any_media` (Enable SIP ALG, RTP allowed between any host (dangerous for untrusted hosts)). | ##### Get the current Connection configuration ###### `GET /connection/config/` Returns the current ConnectionConfiguration Response `result`: ConnectionConfiguration Example request: ```http GET /api/v{version}/connection/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "ping": true, "is_secure_pass": false, "remote_access_port": 80, "remote_access": false, "wol": false, "adblock": false, "adblock_not_set": false, "api_remote_access": true, "allow_token_request": true, "remote_access_ip": "312.13.37.42" } } ``` ##### Update the Connection configuration ###### `PUT /connection/config/` *permission `settings` (inferred)* Updates the ConnectionConfiguration Request body (`application/json`): ConnectionConfiguration Response `result`: ConnectionConfiguration Example request: ```http PUT /api/v{version}/connection/config/ HTTP/1.1 Host: mafreebox.freebox.fr { "ping": true, "wol": false } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "ping": true, "is_secure_pass": false, "remote_access_port": 80, "remote_access": false, "wol": false, "adblock": false, "adblock_not_set": false, "api_remote_access": true, "allow_token_request": true, "remote_access_ip": "312.13.37.42" } } ``` #### Connection IPv6 configuration ##### Connection IPv6 configuration object ###### Object `ConnectionIpv6Delegation` | Property | Type | Access | Description | | --- | --- | --- | --- | | `prefix` | string | | IPv6 prefix | | `next_hop` | string (ipv6) | | the next hop for the prefix | ###### Object `ConnectionIpv6Configuration` | Property | Type | Access | Description | | --- | --- | --- | --- | | `ipv6_enabled` | boolean | | is IPv6 enabled | | `ipv6_firewall` | boolean | | is IPv6 firewall enabled | | `ipv6_prefix_firewall` | boolean | | is IPv6 firewall enabled for delegated prefixes | | `ipv6ll` | string | read-only | Freebox IPv6 link local address | | `delegations` | ConnectionIpv6Delegation[] (max 8) | | list of IPv6 delegations | ##### Get the current IPv6 Connection configuration ###### `GET /connection/ipv6/config/` Returns the current ConnectionIpv6Configuration Response `result`: ConnectionIpv6Configuration Example request: ```http GET /api/v{version}/connection/ipv6/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "ipv6_enabled": true, "ipv6_firewall": false, "ipv6_prefix_firewall": true, "delegations": [ { "prefix": "2a01:e30:d252:a2a0::/64", "next_hop": "" }, { "prefix": "2a01:e30:d252:a2a1::/64", "next_hop": "" }, { "prefix": "2a01:e30:d252:a2a2::/64", "next_hop": "" }, { "prefix": "2a01:e30:d252:a2a3::/64", "next_hop": "" }, { "prefix": "2a01:e30:d252:a2a4::/64", "next_hop": "" }, { "prefix": "2a01:e30:d252:a2a5::/64", "next_hop": "" }, { "prefix": "2a01:e30:d252:a2a6::/64", "next_hop": "" }, { "prefix": "2a01:e30:d252:a2a7::/64", "next_hop": "" } ] } } ``` ##### Update the IPv6 Connection configuration ###### `PUT /connection/ipv6/config/` *permission `settings` (inferred)* Updates the ConnectionIpv6Configuration Request body (`application/json`): ConnectionIpv6Configuration Response `result`: ConnectionIpv6Configuration Example request: *The documentation example uses `PUT /connection/config/`, which differs from the operation path.* ```http PUT /api/v{version}/connection/config/ HTTP/1.1 Host: mafreebox.freebox.fr { "delegations": [ { "prefix": "2a01:e30:d252:a2a2::/64", "next_hop": "fe80::be30:5bff:feb5:fcc7" } ] } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "ipv6_enabled": true, "ipv6_firewall": false, "ipv6_prefix_firewall": false, "ipv6ll": "fe80::224:d4ff:acac:ecec", "delegations": [ { "prefix": "2a01:e30:d252:a2a0::/64", "next_hop": "" }, { "prefix": "2a01:e30:d252:a2a1::/64", "next_hop": "" }, { "prefix": "2a01:e30:d252:a2a2::/64", "next_hop": "fe80::d252:5bff:feb5:fcc7" }, { "prefix": "2a01:e30:d252:a2a3::/64", "next_hop": "" }, { "prefix": "2a01:e30:d252:a2a4::/64", "next_hop": "" }, { "prefix": "2a01:e30:d252:a2a5::/64", "next_hop": "" }, { "prefix": "2a01:e30:d252:a2a6::/64", "next_hop": "" }, { "prefix": "2a01:e30:d252:a2a7::/64", "next_hop": "" } ] } } ``` #### Connection xDSL status [UNSTABLE] ##### xDSL status object [UNSTABLE] ###### Object `XdslStatus` | Property | Type | Access | Description | | --- | --- | --- | --- | | `status` | string | read-only | Values: `down` (unsynchronized), `training` (synchronizing step 1/4), `started` (synchronizing step 2/4), `chan_analysis` (synchronizing step 3/4), `msg_exchange` (synchronizing step 4/4), `showtime` (Ready), `disabled` (Disabled). | | `protocol` | string | read-only | Values: `t1413` (T1.413), `adsl1_a` (ADSL), `adsl2_a` (ADSL2), `adsl2plus_a` (ADSL2+), `readsl2` (ReachDSL), `adsl2_m` (ADSL2 annex M), `adsl2plus_m` (ADSL2+ annex M), `unknown` (Unknown). | | `modulation` | string | read-only | Values: `adsl` (ADSL), `vdsl` (VDSL). | | `uptime` | integer | read-only | uptime in seconds | ##### xDSL stats object [UNSTABLE] ###### Object `XdslStats` | Property | Type | Access | Description | | --- | --- | --- | --- | | `maxrate` | integer | read-only | ATM max rate in kbit/s | | `rate` | integer | read-only | ATM rate in kbit/s | | `snr` | integer | read-only | in dB | | `attn` | integer | read-only | in dB | | `snr_10` | integer | read-only | in dB/10 | | `attn_10` | integer | read-only | in dB/10 | | `fec` | integer | read-only | | | `crc` | integer | read-only | | | `hec` | integer | read-only | | | `es` | integer | read-only | | | `ses` | integer | read-only | | | `phyr` | boolean | read-only | | | `ginp` | boolean | read-only | | | `nitro` | boolean | read-only | | | `rxmt` | integer | read-only | only available when phyr is on | | `rxmt_corr` | integer | read-only | only available when phyr is on | | `rxmt_uncorr` | integer | read-only | only available when phyr is on | | `rtx_tx` | integer | read-only | only available when ginp is on | | `rtx_c` | integer | read-only | only available when ginp is on | | `rtx_uc` | integer | read-only | only available when ginp is on | ##### xDSL infos object [UNSTABLE] ###### Object `XdslInfos` | Property | Type | Access | Description | | --- | --- | --- | --- | | `status` | XdslStatus | | | | `down` | XdslStats | | | | `up` | XdslStats | | | ##### Get the current xDSL infos ###### `GET /connection/xdsl/` *unstable* Returns the current XdslInfos Response `result`: XdslInfos Example request: ```http GET /api/v{version}/connection/xdsl/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "status": { "status": "showtime", "protocol": "adsl2plus_a", "uptime": 5017, "modulation": "adsl" }, "down": { "es": 43, "phyr": true, "attn": 0, "snr": 7, "nitro": true, "rate": 28031, "hec": 0, "crc": 0, "rxmt_uncorr": 0, "rxmt_corr": 0, "ses": 43, "fec": 0, "maxrate": 30636, "rxmt": 0 }, "up": { "es": 0, "phyr": false, "attn": 23, "snr": 15, "nitro": true, "rate": 1022, "hec": 0, "crc": 0, "rxmt_uncorr": 0, "rxmt_corr": 0, "ses": 0, "fec": 0, "maxrate": 1022, "rxmt": 0 } } } ``` #### Connection LTE status [UNSTABLE] ##### LTE radio band object ###### Object `LteRadioBand` | Property | Type | Access | Description | | --- | --- | --- | --- | | `enabled` | boolean | | | | `bandwidth` | integer | | | | `rsrq` | integer | | | | `rsrp` | integer | | | | `rssi` | integer | | | | `band` | integer | | | | `pci` | integer | | | ##### LTE radio object ###### Object `LteRadio` | Property | Type | Access | Description | | --- | --- | --- | --- | | `associated` | boolean | | | | `plmn` | integer | | | | `signal_level` | integer | | | | `gcid` | string | | | | `bands` | any | read-only | | | `ue_active` | boolean | | | ##### LTE network object ###### Object `LteNetwork` | Property | Type | Access | Description | | --- | --- | --- | --- | | `pdn_up` | boolean | | | | `has_ipv6` | boolean | | | | `ipv6_dns` | string | | | | `ipv6` | string | | | | `ipv6_netmask` | string | | | | `has_ipv4` | boolean | | | | `ipv4_dns` | string | | | | `ipv4` | string | | | | `ipv4_netmask` | string | | | ##### LTE sim object ###### Object `LteSim` | Property | Type | Access | Description | | --- | --- | --- | --- | | `present` | boolean | | | | `pin_locked` | boolean | | | | `puk_remaining` | integer | | | | `iccid` | string | | | | `puk_locked` | boolean | | | | `pin_remaining` | integer | | | ##### LTE tunnel details object ###### Object `LteTunnelDetails` | Property | Type | Access | Description | | --- | --- | --- | --- | | `connected` | boolean | | | | `last_error` | string | | | | `tx_flows_rate` | integer | | | | `tx_max_rate` | integer | | | | `tx_used_rate` | integer | | | | `rx_flows_rate` | integer | | | | `rx_max_rate` | integer | | | | `rx_used_rate` | integer | | | ##### LTE tunnel object ###### Object `LteTunnel` | Property | Type | Access | Description | | --- | --- | --- | --- | | `lte` | LteTunnelDetails | | | | `xdsl` | LteTunnelDetails | | | ##### LTE configuration object ###### Object `LteConfiguration` | Property | Type | Access | Description | | --- | --- | --- | --- | | `enabled` | boolean | | | | `radio` | LteRadio | | | | `state` | string | | | | `network` | LteNetwork | | | | `fsm_state` | string | | | | `sim` | LteSim | | | ##### Get the current LTE infos ###### `GET /connection/lte/{id}` *unstable* Returns the current LteConfiguration for the given id. Possible ids are: aggregation backup | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response `result`: LteConfiguration - aggregation - backup Example request: ```http GET /api/v{version}/connection/lte/aggregation HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```text { "success": true, "result": { "enabled": true, "radio": { "associated": true, "plmn": 20202, "signal_level": 5, "gcid": "202020202020", "bands": [], "ue_active": false }, "state": "connected", "network": { "ipv6_dns": "", "ipv6": "2a2a:e0e:beeb:eded::1", "ipv4_netmask": "0.0.0.0", "has_ipv6": true, "ipv4_dns": "0.0.0.0", "has_ipv4": alse, "pdn_up": true, "ipv6_netmask": "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00", "ipv4": "0.0.0.0" }, "fsm_state": "poll_network", "sim": { "present": true, "pin_locked": alse, "puk_remaining": 10, "iccid": "1234567890123456789", "puk_locked":f alse, "pin_remaining": 3 }, } } ``` ##### Get the current xDSL/LTE aggregation infos ###### `GET /connection/aggregation` *unstable* Returns the current LteTunnel Response `result`: { enabled: boolean, tunnel: { lte: { tx_flows_rate: integer, connected: boolean, last_error: string, rx_flows_rate: integer, tx_max_rate: integer, tx_used_rate: integer, rx_max_rate: integer, rx_used_rate: integer }, xdsl: { tx_flows_rate: integer, connected: boolean, last_error: string, rx_flows_rate: integer, tx_max_rate: integer, tx_used_rate: integer, rx_max_rate: integer, rx_used_rate: integer } } } Example request: ```http GET /api/v{version}/connection/aggregation HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": true, "tunnel": { "lte": { "tx_flows_rate": 0, "connected": true, "last_error": "no_error", "rx_flows_rate": 0, "tx_max_rate": 0, "tx_used_rate": 0, "rx_max_rate": 0, "rx_used_rate": 0 }, "xdsl": { "tx_flows_rate": 0, "connected": true, "last_error": "no_error", "rx_flows_rate": 0, "tx_max_rate": 4428750, "tx_used_rate": 134, "rx_max_rate": 12502000, "rx_used_rate": 120 } } } } ``` ##### Update the xDSL/LTE aggregation configuration ###### `PUT /connection/aggregation` *permission `settings` (inferred) · unstable* Updates the LteConfiguration Request body (`application/json`): LteConfiguration Response `result`: LteConfiguration Example request: ```http PUT /api/v{version}/connection/aggregation/ HTTP/1.1 Host: mafreebox.freebox.fr { "enabled": true } ``` #### Connection FTTH status [UNSTABLE] ##### FTTH status object [UNSTABLE] ###### Object `FtthStatus` | Property | Type | Access | Description | | --- | --- | --- | --- | | `sfp_present` | boolean | read-only | | | `sfp_alim_ok` | boolean | read-only | | | `sfp_has_power_report` | boolean | read-only | | | `sfp_has_signal` | boolean | read-only | | | `link` | boolean | read-only | | | `sfp_serial` | string | read-only | | | `sfp_model` | string | read-only | | | `sfp_vendor` | string | read-only | | | `sfp_pwr_tx` | integer | read-only | scaled by 100 (in dBm) | | `sfp_pwr_rx` | integer | read-only | scaled by 100 (in dBm) | ##### Get the current FTTH status ###### `GET /connection/ftth/` *unstable* Returns the current FtthStatus Response `result`: FtthStatus Example request: ```http GET /api/v{version}/connection/ftth/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "sfp_has_power_report": true, "sfp_has_signal": false, "sfp_model": "SPBD-1250E4H2RDB", "sfp_vendor": "DELTA", "sfp_pwr_tx": -1172, "sfp_pwr_rx": -3698, "link": false, "sfp_alim_ok": true, "sfp_serial": "DE104900000471", "sfp_present": true } } ``` #### Connection DynDNS status ##### DynDnsProvider status object ###### Object `DDNSStatus` | Property | Type | Access | Description | | --- | --- | --- | --- | | `status` | string | | Values: `disabled` (Disabled), `ok` (Ok), `wait` (Updating), `reqfail` (Request failed), `authfail` (Authentication error), `nocredential` (Invalid credential), `ipinval` (Invalid IP), `hostinval` (Invalid hostname), `abuse` (Blocked because of abuse), `dnserror` (DNS error), `unavailable` (Service unavailable), `nowan` (Unable to get wan IP), `unknown` (Unknown). | | `next_refresh` | integer | | next refresh timestamp | | `last_refresh` | integer | | last refresh timestamp | | `next_retry` | integer | | next retry timestamp | | `last_error` | integer | | last error timestamp | ##### Get the status of a DynDNS service Right now the supported dynamic dns providers are: - ovh - dyndns - noip ###### `GET /connection/ddns/{provider}/status/` Returns the current DDNSStatus | Parameter | In | Type | Description | | --- | --- | --- | --- | | `provider` | path | string | | Response `result`: DDNSStatus Example request: ```http GET /api/v{version}/connection/ddns/dyndns/status/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "last_error": 1354127350, "status": "hostinval", "next_refresh": 0, "last_refresh": 0, "next_retry": 0 } } ``` #### Connection DynDNS configuration ##### DynDns config object ###### Object `DDNSConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `enabled` | boolean | | | | `hostname` | string | | dns name to use to register | | `password` | string | write-only | password to use to register | | `user` | string | | username to use to register | ##### Get the config of a DynDNS service ###### `GET /connection/ddns/{provider}/` Returns the current DDNSConfig | Parameter | In | Type | Description | | --- | --- | --- | --- | | `provider` | path | string | | Response `result`: DDNSConfig Example request: ```http GET /api/v{version}/connection/ddns/dyndns/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": true, "hostname": "test", "user": "test" } } ``` ##### Set the config of a DynDNS service ###### `PUT /connection/ddns/{provider}/` *permission `settings` (inferred)* Set the DDNSConfig | Parameter | In | Type | Description | | --- | --- | --- | --- | | `provider` | path | string | | Request body (`application/json`): DDNSConfig Response `result`: DDNSConfig Example request: ```http PUT /api/v{version}/connection/ddns/dyndns/ HTTP/1.1 Host: mafreebox.freebox.fr { "enabled": false, "user": "test", "password": "ssss", "hostname": "ttt" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": false, "hostname": "ttt", "user": "test" } } ``` ### Lan With the LAN API you get information and modify the Freebox Server network configuration. #### Lan Errors When attempting to access the LAN API, you may encounter the following errors: | error_code | Description | | --- | --- | | noent | Invalid id | | internal_error | Internal error | | ioerror | Internal error | | inval | Invalid parameter | | invalid_gateway_ip | Invalid Gateway IP | | invalid_route | Invalid static route | | exists | Duplicate route prefix | #### Lan Config Lan config has the following attributes: ##### Object `LanConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `ip` | string | | Freebox Server IPv4 address | | `local_domain` | string | | Freebox Server local domain (max length: 63) | | `name` | string | | Freebox Server name | | `name_dns` | string | | Freebox Server DNS name | | `name_mdns` | string | | Freebox Server mDNS name | | `name_netbios` | string | | Freebox Server netbios name | | `type` | string | | The valid LAN modes are: NOTE: in bridge mode, most of Freebox services are disabled. It is recommended to use the router mode, and third party apps should not change this setting Values: `router` (The Freebox acts as a network router), `bridge` (The Freebox acts as a network bridge). | #### Route A route has the following attributes: ##### Object `Route` | Property | Type | Access | Description | | --- | --- | --- | --- | | `prefix` | string | | Destination network IPv4 prefix in CIDR format (e.g. 192.168.1.0/24). A prefix is considered invalid if it is a subprefix of any reserved network listed below. Only one enabled route may exist for a given prefix. An exists error will be returned if multiple active routes share the same prefix. Documented values: `127.0.0.0/8` (Loopback network), `169.254.0.0/16` (Link-local addresses), `224.0.0.0/4` (IANA: multicast), `192.168.27.0/24` (Used for VPN and guest WIFI addresses). | | `gateway` | string | | IP address of the next-hop gateway. | | `enabled` | boolean | | If false the route is not added to the routing table. | | `description` | string | | Optional text describing the route. | #### Lan Config API ##### Get the current Lan configuration ###### `GET /lan/config/` Returns the current LanConfig Response `result`: LanConfig Example request: ```http GET /api/v{version}/lan/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "local_domain": "home.arpa", "name_dns": "freebox-r0ro", "name_mdns": "Freebox-r0ro", "name": "Freebox r0ro", "mode": "router", "name_netbios": "Freebox_r0ro", "ip": "192.168.1.254" } } ``` ##### Update the current Lan configuration ###### `PUT /lan/config/` *permission `settings` (inferred)* Update the current LanConfig Request body (`application/json`): LanConfig Response `result`: LanConfig Example request: ```http PUT /api/v{version}/lan/config/ HTTP/1.1 Host: mafreebox.freebox.fr { "mode": "router", "ip": "192.168.69.254", "local_domain": "home.arpa", "name": "Freebox de r0ro", "name_dns": "freebox-de-r0ro", "name_mdns": "Freebox-de-r0ro", "name_netbios": "Freebox_de_r0ro" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "local_domain": "home.arpa", "name_dns": "freebox-de-r0ro", "name_mdns": "Freebox-de-r0ro", "name": "Freebox de r0ro", "mode": "router", "name_netbios": "Freebox_de_r0ro", "ip": "192.168.69.254" } } ``` #### Routing Config API ##### Get the current routing configuration ###### `GET /lan/routes` Returns the current list of Route objects Response `result`: Route[] Example request: ```http GET /api/v{version}/lan/routes/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "prefix": "192.168.42.0/24", "gateway": "192.168.1.38", "enabled": true, "description": "My first route" }, { "prefix": "192.168.24.240/28", "gateway": "192.168.1.38", "enabled": false, "description": "" } ] } ``` ##### Update the current routing configuration ###### `PUT /lan/routes/` *permission `settings` (inferred)* Update the current list of Route objects Request body (`application/json`): { prefix: string, gateway: string, enabled: boolean, description: string }[] Response `result`: Route[] Example request: ```http PUT /api/v{version}/lan/routes/ HTTP/1.1 Host: mafreebox.freebox.fr [ { "prefix": "192.168.42.0/24", "gateway": "192.168.1.38", "enabled": true, "description": "My first and only route" } ] ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "prefix": "192.168.42.0/24", "gateway": "192.168.1.38", "enabled": true, "description": "My first and only route" } ] } ``` ### Lan Browser With the LAN browser API you get information on hosts on the Freebox Server local network. #### Errors When attempting to access the LAN browser API, you may encounter the following errors: | error_code | Description | | --- | --- | | inval | Invalid parameter | | nodev | Invalid interface | | nohost | Invalid host id | | nomem | Internal error | | netdown | Network is down | #### Lan Browser API Lan browser API allow you to discover hosts on the local network ##### Getting the list of browsable LAN interfaces ###### `GET /lan/browser/interfaces/` Response `result`: { name: string, host_count: integer }[] Example request: ```http GET /api/v{version}/lan/browser/interfaces/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "name": "pub", "host_count": 3 } ] } ``` ##### Lan Host object Lan Host has the following attributes: ###### Object `LanHost` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | string | read-only | Host id (unique on this interface) | | `primary_name` | string | | Host primary name (chosen from the list of available names, or manually set by user) | | `local_domain` | string | read-only | Local domain the host’s domain must be part of. | | `domain_name` | string | | Host domain name on the local network (manually set by user, or automatically configured during device registration). The string must respect the following rules: Ends with ‘.{local_domain}’ 255 characters long at max Only alphabetical characters are accepted Digits are accepted provided they are not placed at the beginning of the string, nor after another dot character. Hyphens and dots are accepted provided they are not placed at the beginning or the end of the string, nor after or before another dot character. It is also possible to use an empty string. This special value means no local domain should be registered for this host. | | `host_type` | string | | When possible, the Freebox will try to guess the host_type, but you can manually override this to the correct value Possible values are: Values: `workstation` (Workstation), `laptop` (Laptop), `smartphone` (Smartphone), `tablet` (Tablet), `printer` (Printer), `vg_console` (Video game console), `television` (TV), `nas` (Nas), `ip_camera` (IP Camera), `ip_phone` (IP Phone), `freebox_player` (Freebox Player), `freebox_hd` (Freebox HD), `freebox_crystal` (Freebox Crystal), `freebox_mini` (Freebox Mini 4k), `freebox_delta` (Freebox Delta), `freebox_one` (Freebox One), `freebox_wifi` (Freebox Wi-Fi Pop), `freebox_pop` (Freebox Pop), `networking_device` (Networking device), `multimedia_device` (Multimedia device), `car` (Connected car), `watch` (Smartwatch), `light` (Light), `outlet` (Connected outlet), `appliances` (Household appliances), `thermostat` (Thermostat), `shutter` (Electric shutter), `other` (Other). | | `primary_name_manual` | boolean | read-only | If true the primary name has been set manually | | `l2ident` | LanHostL2Ident | read-only | Layer 2 network id and its type **Correction:** Documented as an array, returned as a single object (checked with GET /lan/browser/pub/ on Freebox OS 4.11.1 and 4.13.1). | | `vendor_name` | string | read-only | Host vendor name (from the mac address) | | `persistent` | boolean | | If true the host is always shown even if it has not been active since the Freebox startup | | `reachable` | boolean | read-only | If true the host can receive traffic from the Freebox | | `last_time_reachable` | integer (unix-time) | read-only | UNIX timestamp (seconds) Last time the host was reached | | `active` | boolean | read-only | If true the host sends traffic to the Freebox | | `last_activity` | integer (unix-time) | read-only | UNIX timestamp (seconds) Last time the host sent traffic | | `first_activity` | integer (unix-time) | read-only | UNIX timestamp (seconds) First time the host sent traffic, or 0 (Unix Epoch) if it wasn’t seen before this field was added. | | `names` | LanHostName[] | read-only | List of available names, and their source | | `l3connectivities` | LanHostL3Connectivity[] | read-only | List of available layer 3 network connections | | `network_control` | LanHostNetworkControl | read-only | If device is associated with a profile, contains profile summary. | | `info` | object | read-only | Contains detailed information that could be gathered about the device. | ###### Object `LanHostName` | Property | Type | Access | Description | | --- | --- | --- | --- | | `name` | string | read-only | Host name | | `source` | string | read-only | source of the name | ###### Object `LanHostL2Ident` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | string | read-only | Layer 2 id | | `type` | string | read-only | Type of layer 2 address **Correction:** The value table is copied from LanHostName.source; the box returns mac_address (checked with GET /lan/browser/pub/ on Freebox OS 4.11.1 and 4.13.1). | ###### Object `LanHostL3Connectivity` | Property | Type | Access | Description | | --- | --- | --- | --- | | `addr` | string | read-only | Layer 3 address | | `af` | string | read-only | Values: `ipv4` (IPv4), `ipv6` (IPv6). | | `active` | boolean | read-only | is the connection active | | `reachable` | boolean | read-only | is the connection reachable | | `last_activity` | integer (unix-time) | read-only | UNIX timestamp (seconds) last activity timestamp | | `last_time_reachable` | integer (unix-time) | read-only | UNIX timestamp (seconds) last reachable timestamp | | `model` | string | read-only | device model if known | ###### Object `LanHostNetworkControl` | Property | Type | Access | Description | | --- | --- | --- | --- | | `profile_id` | integer | read-only | Id of profile this device is associated with. | | `name` | string | read-only | Name of profile this device is associated with. | | `current_mode` | string | read-only | Mode described in Network Control Object | ##### Getting the list of hosts on a given interface ###### `GET /lan/browser/{interface}/` Returns the list of LanHost on this interface | Parameter | In | Type | Description | | --- | --- | --- | --- | | `interface` | path | string | | Response `result`: LanHost[] Example request: ```http GET /api/v{version}/lan/browser/pub/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "l2ident": { "id": "d0:23:db:36:15:aa", "type": "mac_address" }, "active": true, "id": "ether-d0:23:db:36:15:aa", "last_time_reachable": 1360669498, "persistent": true, "names": [ { "name": "iPhone-r0ro", "source": "dhcp" } ], "vendor_name": "Apple, Inc.", "l3connectivities": [ { "addr": "192.168.69.20", "active": true, "af": "ipv4", "reachable": true, "last_activity": 1360669498, "last_time_reachable": 1360669498 } ], "reachable": true, "last_activity": 1360669498, "primary_name_manual": true, "primary_name": "iPhone r0ro", "domain_name": "iphone-r0ro.home.arpa", "local_domain": "home.arpa", "info": {} }, { "l2ident": { "id": "00:24:d4:7e:00:4c", "type": "mac_address" }, "active": true, "id": "ether-00:24:d4:7e:00:4c", "last_time_reachable": 1360669491, "persistent": false, "names": [ { "name": "Freebox Player", "source": "dhcp" } ], "vendor_name": "FREEBOX SA", "l3connectivities": [ { "addr": "192.168.69.30", "active": true, "af": "ipv4", "reachable": true, "last_activity": 1360669491, "last_time_reachable": 1360669491 } ], "reachable": true, "last_activity": 1360669491, "primary_name_manual": false, "primary_name": "Freebox Player", "domain_name": "", "local_domain": "home.arpa", "info": { "upnp": { "modelName": "Freebox Player", "friendlyName": "Freebox Player", "manufacturer": "Freebox", "service[0]": "urn:dial-multiscreen-org:serviceId:dial", "deviceType": "urn:dial-multiscreen-org:device:dial:1" }, "mdns": { "Service: raop": "192.168.1.91:5000 (tcp)", "Service: hid": "192.168.1.91:24322 (udp)", "Service: airplay": "192.168.1.91:7000 (tcp)", "Service: amzn-alexa": "192.168.1.91 (tcp)" }, "dhcp": { "Host Name": "Freebox Player" } } } ] } ``` ##### Getting an host information ###### `GET /lan/browser/{interface}/{hostid}/` Returns the requested LanHost properties | Parameter | In | Type | Description | | --- | --- | --- | --- | | `interface` | path | string | | | `hostid` | path | string | | Response `result`: LanHost Example request: ```http GET /api/v{version}/lan/browser/pub/ether-00:24:d4:7e:00:4c/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "l2ident": { "id": "00:24:d4:7e:00:4c", "type": "mac_address" }, "active": true, "id": "ether-00:24:d4:7e:00:4c", "last_time_reachable": 1360669611, "persistent": false, "names": [ { "name": "Freebox Player", "source": "dhcp" } ], "vendor_name": "FREEBOX SA", "l3connectivities": [ { "addr": "192.168.69.30", "active": true, "af": "ipv4", "reachable": true, "last_activity": 1360669611, "last_time_reachable": 1360669611 } ], "reachable": true, "last_activity": 1360669611, "primary_name_manual": false, "primary_name": "Freebox Player", "domain_name": "", "local_domain": "home.arpa", "info": { "upnp": { "modelName": "Freebox Player", "friendlyName": "Freebox Player", "manufacturer": "Freebox", "service[0]": "urn:dial-multiscreen-org:serviceId:dial", "deviceType": "urn:dial-multiscreen-org:device:dial:1" }, "mdns": { "Service: raop": "192.168.1.91:5000 (tcp)", "Service: hid": "192.168.1.91:24322 (udp)", "Service: airplay": "192.168.1.91:7000 (tcp)", "Service: amzn-alexa": "192.168.1.91 (tcp)" }, "dhcp": { "Host Name": "Freebox Player" } } } } ``` ##### Updating an host information ###### `PUT /lan/browser/{interface}/{hostid}/` *permission `settings` (inferred)* Update a LanHost properties | Parameter | In | Type | Description | | --- | --- | --- | --- | | `interface` | path | string | | | `hostid` | path | string | | Request body (`application/json`): LanHost Response `result`: LanHost Example request: ```http PUT /api/v{version}/lan/browser/pub/ether-00:24:d4:7e:00:4c/ HTTP/1.1 Host: mafreebox.freebox.fr { "id": "ether-00:24:d4:7e:00:4c", "primary_name": "Freebox Tv" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "l2ident": { "id": "00:24:d4:7e:00:4c", "type": "mac_address" }, "active": true, "id": "ether-00:24:d4:7e:00:4c", "last_time_reachable": 1360669851, "persistent": true, "names": [ { "name": "Freebox Player", "source": "dhcp" } ], "vendor_name": "FREEBOX SA", "l3connectivities": [ { "addr": "192.168.69.30", "active": true, "af": "ipv4", "reachable": true, "last_activity": 1360669851, "last_time_reachable": 1360669851 } ], "reachable": true, "last_activity": 1360669851, "primary_name_manual": true, "primary_name": "Freebox Tv", "domain_name": "", "local_domain": "home.arpa", "info": { "upnp": { "modelName": "Freebox Player", "friendlyName": "Freebox Player", "manufacturer": "Freebox", "service[0]": "urn:dial-multiscreen-org:serviceId:dial", "deviceType": "urn:dial-multiscreen-org:device:dial:1" }, "mdns": { "Service: raop": "192.168.1.91:5000 (tcp)", "Service: hid": "192.168.1.91:24322 (udp)", "Service: airplay": "192.168.1.91:7000 (tcp)", "Service: amzn-alexa": "192.168.1.91 (tcp)" }, "dhcp": { "Host Name": "Freebox Player" } } } } ``` ##### Getting available lan host types ###### `GET /lan/browser/types/` Get available LanHost types Response `result`: { icon: string, type: string, name: string, category: string }[] Example request: ```http GET /api/v{version}/lan/browser/types/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "icon": "/resources/images/lan/ic_device_computer.png", "type": "workstation", "name": "Ordinateur", "category": "personal_device" }, { "icon": "/resources/images/lan/ic_device_printer.png", "type": "printer", "name": "Imprimante", "category": "network" } ] } ``` #### Wake on LAN ##### Send Wake ok Lan packet to an host ###### `POST /lan/wol/{interface}/` *permission `settings` (inferred)* Send a wake on LAN packet to the specified host with an optional password | Parameter | In | Type | Description | | --- | --- | --- | --- | | `interface` | path | string | | Request body (`application/json`): { mac: string, password: string } Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http POST /api/v{version}/lan/wol/pub/ HTTP/1.1 Host: mafreebox.freebox.fr { "mac": "00:24:d4:7e:00:4c", "password": "" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ### Freeplug The freeplug API allow you to list the freeplugs on the Freebox network and get stats #### Freeplug Errors When attempting to access the freeplug API, you may encounter the following errors: | error_code | Description | | --- | --- | | inval | Invalid request | | nomem | Internal error | | nosta | No freeplug with this id | | nopeer | No freeplug with this id | #### Freeplug Network FreeplugNetwork has the following attributes: ##### Object `FreeplugNetwork` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | string | read-only | Network unique id | | `members` | Freeplug[] | read-only | List of freeplugs member of this network | #### Freeplug Object Freeplug has the following attributes: ##### Object `Freeplug` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | string | read-only | Freeplug unique id | | `local` | boolean | read-only | if true the Freeplug is connected directly to the Freebox | | `net_role` | string | read-only | Freeplug network role Values: `sta` (Freeplug Station), `pco` (Freeplug proxy coordinator), `cco` (Central coordinator). | | `model` | string | read-only | Freebox Server netbios name | | `eth_port_status` | string | read-only | Values: `up` (The ethernet port is up), `down` (The ethernet port is down), `unknown` (The ethernet port state is unknown). | | `eth_full_duplex` | boolean | read-only | ethernet link is full duplex | | `has_network` | boolean | read-only | is connected to the network | | `eth_speed` | integer | read-only | ethernet port speed | | `inactive` | integer | read-only | seconds since last activity | | `net_id` | string | read-only | network id | | `rx_rate` | integer | read-only | rx rate (from the freeplugs to the “cco” freeplug) (in Mb/s) -1 if not available | | `tx_rate` | integer | read-only | tx rate (from the “cco” freeplug to the freeplugs) (in Mb/s) -1 if not available | #### Freeplug API ##### Get the current Freeplugs networks ###### `GET /freeplug/` Returns the list of FreeplugNetwork Response `result`: FreeplugNetwork[] Example request: ```http GET /api/v{version}/freeplug/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "id": "c8:f7:b9:83:f5:10:01", "members": [ { "id": "00:24:D4:36:4C:CF", "tx_rate": 148, "eth_port_status": "up", "rx_rate": 148, "net_role": "sta", "inactive": 1, "net_id": "c8:f7:b9:83:f5:10:01", "model": "int6400", "eth_speed": 100, "local": true, "eth_full_duplex": true, "has_network": true }, { "id": "F4:CA:E5:1D:46:AE", "tx_rate": 149, "eth_port_status": "up", "rx_rate": 148, "net_role": "sta", "inactive": 1, "net_id": "c8:f7:b9:83:f5:10:01", "model": "int6400", "eth_speed": 100, "local": true, "eth_full_duplex": true, "has_network": true }, { "id": "00:24:D4:1B:15:D0", "tx_rate": -1, "eth_port_status": "up", "rx_rate": -1, "net_role": "cco", "inactive": 1, "net_id": "c8:f7:b9:83:f5:10:01", "model": "int6400", "eth_speed": 100, "local": false, "eth_full_duplex": true, "has_network": true } ] } ] } ``` ##### Get a particular Freeplug information ###### `GET /freeplug/{id}/` Returns the list of Freeplug | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response `result`: Freeplug Example request: ```http GET /api/v{version}/freeplug/F4:CA:E5:1D:46:AE/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "id": "00:24:D4:36:4C:CF", "tx_rate": -1, "eth_port_status": "up", "rx_rate": -1, "net_role": "sta", "inactive": 1, "net_id": "c8:f7:b9:83:f5:10:01", "model": "int6400", "eth_speed": 100, "local": true, "eth_full_duplex": true, "has_network": true } } ``` ##### Reset a Freeplug ###### `POST /freeplug/{id}/reset/` *permission `settings` (inferred)* reset the given Freeplug | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http POST /api/v{version}/freeplug/F4:CA:E5:1D:46:AE/reset/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ### DHCP With the DHCP API you configure the Freebox dhcp server, and access its status. #### DHCP Errors When attempting to access the DHCP API, you may encounter the following errors: | error_code | Description | | --- | --- | | inval | invalid argument | | inval_netmask | invalid netmask | | inval_ip_range | invalid IP range | | inval_ip_range_net | IP range & netmask mismatch | | inval_gw_net | gateway & netmask mismatch | | exist | already exists | | nodev | no such device | | noent | no such entry | | netdown | network is down | | busy | device or resource busy | #### DHCP Config Object DHCP config has the following attributes: ##### Object `DhcpConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `enabled` | boolean | | Enable/Disable the DHCP server | | `sticky_assign` | boolean | | Always assign the same IP to a given host | | `gateway` | string | read-only | Gateway IP address | | `netmask` | string | read-only | Gateway subnet netmask | | `ip_range_start` | string | | DHCP range start IP | | `ip_range_end` | string | | DHCP range end IP | | `always_broadcast` | boolean | | Always broadcast DHCP responses | | `ignore_out_of_range_hint` | boolean | | Ignore requested address if it is outside of the DHCP range | | `boot_server` | string | | Address of the TFTP server used when booting via TFTP. | | `boot_file` | string | | Boot file to download from the TFTP server when booting via TFTP. | | `dns` | string[] | | List of dns servers to include in DHCP reply | | `options` | DhcpOption[] \| {} (empty object) | | List of dns options to include in DHCP reply **Correction:** Empty list returned as {} (checked with GET /dhcp/config/ on Freebox OS 4.11.1 and 4.13.1). Empty lists are serialized as {} by the box. | #### DHCP Option Object DHCP options have the following attributes ##### Object `DhcpOption` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | string | read-only | The valid option identifiers and types are: Documented values: `time_offset` (s32 Time offset), `time_server` (ip_list Time server), `log_server` (ip_list Log server), `cookie_server` (ip_list Cookie server), `lpr_server` (ip_list LPR server), `impress_server` (ip_list Impress server), `resource_location_server` (ip_list Resource location server), `hostname` (string Hostname), `merit_dump_file` (string Merit dump file), `domain_name` (string Domain name), `swap_server` (ip_list Swap server), `root_path` (string Root path), `extensions_path` (string Extensions path), `ip_fwd` (bool IP forwarding), `ip_fwd_non_local` (bool Non-local IP source routing), `ip_max_reassembly_size` (u16 Maximum IP reassembly size), `ip_ttl` (u8 Default IP TTL), `ip_pmtu_timeout` (u32 IP Path MTU timeout), `mtu` (u16 Interface MTU), `local_subnets` (bool All subnets are local), `mask_discovery` (bool Perform mask discovery), `mask_supplier` (bool Mask supplier), `perform_rd` (bool Perform router discovery), `rs_address` (ip Router solicitation address), `trailer_encapsulation` (bool Trailer encapsulation), `arp_cache_timeout` (u32 ARP cache timeout), `eth_encapsulation` (bool Ethernet encapsulation), `tcp_ttl` (u8 Default TCP TTL), `tcp_keepalive_interval` (u32 TCP keepalive interval), `tcp_keepalive_garbage` (bool TCP keepalive garbage), `nis_domain` (string NIS domain), `nis_server` (ip_list NIS server), `ntp_server` (ip_list NTP server), `vendor_specific` (hexstring Vendor specific information), `nis_plus_domain` (string NIS+ domain), `nis_plus_server` (ip_list NIS+ server), `tftp_server_name` (string TFTP server name), `bootfile_name` (string Bootfile name), `mobile_ip_agent` (ip_list Mobile IP home agent), `smtp_server` (ip_list SMTP server), `pop3_server` (ip_list POP3 server), `nntp_server` (ip_list NNTP server), `www_server` (ip_list Default WWW server), `finger_server` (ip_list Default Finger server), `irc_server` (ip_list Default IRC server), `streettalk_server` (ip_list StreetTalk server), `stda_server` (ip_list StreetTalk directory assistance server), `slp_directory_agent` (ip_list SLP directory agent), `slp_service_scope` (hexstring SLP service scope), `nds_servers` (ip_list NDS servers), `nds_tree_name` (string NDS tree name), `nds_context` (string NDS context), `ldap_servers` (ip_list LDAP servers), `timezone_posix` (string Timezone POSIX), `timezone_database` (string Timezone database), `name_service` (hexstring Name service), `domain_search` (hexstring Domain search), `classless_static_route` (hexstring Classless static route), `capwap_ac` (ip_list CAPWAP access controller), `tftp_server_address` (ip_list TFTP server address). | | `val` | string | | The value sent by the DHCP server when this option is requested by the client. The formats depend on the option type: ip: A single IPv4 address (as described in RFC 791) ip_list: A comma-separated list of IPv4 addresses string: A string of ASCII characters hexstring: A string of ASCII hexadecimal characters [0-9a-fA-F] representing a binary value (example: C0A801FE) bool: one of [ ‘true’, ‘false’, ‘1’, ‘0’ ] s8, s16, s32: An n-bit signed integer value u8, u16, u32: An n-bit unsigned integer value | #### DHCP Configuration API ##### Get the current DHCP configuration ###### `GET /dhcp/config/` Returns the current DhcpConfig Response `result`: DhcpConfig Example request: ```http GET /api/v{version}/dhcp/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": true, "gateway": "192.168.1.254", "sticky_assign": true, "ip_range_end": "192.168.1.50", "netmask": "255.255.255.0", "boot_server": "", "boot_file": "", "dns": [ "192.168.1.254", "", "", "", "" ], "always_broadcast": false, "ip_range_start": "192.168.1.2", "options": [ { "id": "ip_fwd", "val": "true" }, { "id": "tcp_ttl", "val": "64" }, { "id": "ntp_server", "val": "192.168.1.38, 192.168.1.42" }, { "id": "log_server", "val": "192.168.1.38" } ] } } ``` ##### Update the current DHCP configuration ###### `PUT /dhcp/config/` *permission `settings` (inferred)* Update the current DhcpConfig Request body (`application/json`): DhcpConfig Response `result`: DhcpConfig Example request: ```http PUT /api/v{version}/dhcp/config/ HTTP/1.1 Host: mafreebox.freebox.fr { "enabled": false } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": false, "gateway": "192.168.1.254", "sticky_assign": true, "ip_range_end": "192.168.1.50", "netmask": "255.255.255.0", "dns": [ "192.168.1.254", "", "", "", "" ], "always_broadcast": false, "ip_range_start": "192.168.1.2", "options": [ { "id": "ip_fwd", "val": "true" }, { "id": "tcp_ttl", "val": "64" }, { "id": "ntp_server", "val": "192.168.1.38, 192.168.1.42" }, { "id": "log_server", "val": "192.168.1.38" } ] } } ``` #### DHCP Static Lease Object DHCP static lease have the following attributes ##### Object `DhcpStaticLease` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | string | | DHCP static lease object id | | `mac` | string | | Host mac address | | `comment` | string | | an optional comment | | `hostname` | string | read-only | hostname matching the mac address | | `ip` | string | | IPv4 to assign to the host | | `host` | LanHost | read-only | LAN host information from LAN browser (refer to LanHost documentation) | | `options` | DhcpOption[] \| {} (empty object) | | List of dns options to include in DHCP reply **Correction:** Empty list returned as {} (checked with GET /dhcp/static_lease/ on Freebox OS 4.11.1 and 4.13.1). Empty lists are serialized as {} by the box. | #### DHCP Static Lease API ##### Get the list of DHCP static leases You can get the list of `DhcpStaticLease` using this API ###### `GET /dhcp/static_lease/` Response `result`: DhcpStaticLease[] Example request: ```http GET /api/v{version}/dhcp/static_lease/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "mac": "00:DE:AD:B0:0B:55", "comment": "", "hostname": "Pc de r0ro", "id": "00:DE:AD:B0:0B:55", "host": {}, "ip": "192.168.1.1", "options": [ { "id": "log_server", "val": "192.168.1.38" } ] }, { "mac": "00:DE:AD:B0:0B:69", "comment": "", "hostname": "Imprimante", "id": "00:DE:AD:B0:0B:69", "host": {}, "ip": "192.168.1.2", "options": [] } ] } ``` ##### Get a given DHCP static lease You can get a specific `DhcpStaticLease` with its id ###### `GET /dhcp/static_lease/{id}` | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response `result`: DhcpStaticLease Example request: ```http GET /api/v{version}/dhcp/static_lease/00:DE:AD:B0:0B:55 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "mac": "00:DE:AD:B0:0B:55", "comment": "", "hostname": "Pc de r0ro", "id": "00:DE:AD:B0:0B:55", "host": {}, "ip": "192.168.1.1", "options": [ { "id": "log_server", "val": "192.168.1.38" } ] } } ``` ##### Update DHCP static lease You can update a `DhcpStaticLease` with this method ###### `PUT /dhcp/static_lease/{id}` *permission `settings` (inferred)* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Request body (`application/json`): { comment: string } Response `result`: DhcpStaticLease Example request: ```http PUT /api/v{version}/dhcp/static_lease/00:DE:AD:B0:0B:55 HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "comment": "Mon PC" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "mac": "00:DE:AD:B0:0B:55", "comment": "Mon PC", "hostname": "Pc de r0ro", "id": "00:DE:AD:B0:0B:55", "host": {}, "ip": "192.168.1.1", "options": [ { "id": "log_server", "val": "192.168.1.38" } ] } } ``` ##### Delete a DHCP static lease Deletes the `DhcpStaticLease` with this id ###### `DELETE /dhcp/static_lease/{id}` *permission `settings` (inferred)* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/dhcp/static_lease/00:DE:AD:B0:0B:55 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Add a DHCP static lease ###### `POST /dhcp/static_lease/` *permission `settings` (inferred)* Request body (`application/json`): { ip: string, mac: string } Response `result`: DhcpStaticLease Example request: ```http POST /api/v{version}/dhcp/static_lease/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "ip": "192.168.1.222", "mac": "00:00:00:11:11:11" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "mac": "00:00:00:11:11:11", "comment": "", "hostname": "00:00:00:11:11:11", "id": "00:00:00:11:11:11", "ip": "192.168.1.222", "options": [] } } ``` #### DHCP Dynamic Lease Object DHCP dynamic lease have the following attributes ##### Object `DhcpDynamicLease` | Property | Type | Access | Description | | --- | --- | --- | --- | | `mac` | string | read-only | Host mac address | | `hostname` | string | read-only | hostname matching the mac address | | `ip` | string | read-only | IPv4 assigned to the host | | `lease_remaining` | integer | read-only | time left before lease needs to be refreshed | | `assign_time` | integer (unix-time) | read-only | UNIX timestamp (seconds) timestamp of the lease first assignment | | `refresh_time` | integer (unix-time) | read-only | UNIX timestamp (seconds) timestamp of the last lease refresh | | `is_static` | boolean | read-only | is the lease static | | `host` | LanHost | read-only | LAN host information from LAN browser (refer to LanHost documentation) | ##### Get the list of DHCP dynamic leases You can get the list of `DhcpDynamicLease` using this API ###### `GET /dhcp/dynamic_lease/` Response `result`: DhcpDynamicLease[] Example request: ```http GET /api/v{version}/dhcp/dynamic_lease/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "mac": "13:37:00:00:01:03", "host": { "l2ident": { "id": "13:37:00:00:01:03", "type": "mac_address" }, "active": true, "id": "ether-13:37:00:00:01:03", "last_time_reachable": 1555555555, "persistent": false, "names": [], "vendor_name": "", "host_type": "", "primary_name": "", "l3connectivities": [ { "addr": "192.168.1.1", "active": true, "reachable": true, "last_activity": 1555555555, "af": "ipv4", "last_time_reachable": 1555555555 }, { "addr": "fe80::ffff:3333:eeee:eee", "active": false, "reachable": false, "last_activity": 1555585108, "af": "ipv6", "last_time_reachable": 1555585103 } ], "reachable": true, "last_activity": 1555555555, "primary_name_manual": false, "interface": "pub" }, "refresh_time": 1555555555, "hostname": "android r0ro", "assign_time": 1555555555, "lease_remaining": 123456, "is_static": false, "ip": "192.168.1.22", "options": [ { "id": "ip_fwd", "val": "true" }, { "id": "tcp_ttl", "val": "64" }, { "id": "ntp_server", "val": "192.168.1.38, 192.168.1.42" }, { "id": "log_server", "val": "192.168.1.38" } ] } ] } ``` ### DHCPv6 With the DHCPv6 API you configure the Freebox DHCPv6 server, and access its status. #### DHCPv6 Errors When attempting to access the DHCPv6 API, you may encounter the following errors: | error_code | Description | | --- | --- | | inval | invalid parameter | | noent | no such entry | | nospc | too many entries | | exist | already exists | | conflict | conflict with another rule | | nomem | internal error | #### DHCPv6 Config Object DHCPv6 config has the following attributes: ##### Object `DHCPv6Config` | Property | Type | Access | Description | | --- | --- | --- | --- | | `enabled` | boolean | | Enable/Disable the DHCPv6 server NOTE: on some Android devices, enabling the DHCPv6 server may cause IPv6 to stop working on those devices | | `use_custom_dns` | boolean | | if set to true, the user provided IPv6 dns servers will be used instead of Free default IPv6 dns servers NOTE: even if DHCPv6 server is disabled the custom dns can be used to replace Free dns in RA RDNSS | | `dns` | (string (ipv6))[] \| {} (empty object) | | list of ipv6 dns servers to use instead of Free dns servers in case use_custom_dns is set to true **Correction:** Empty list returned as {} (checked with GET /dhcpv6/config/ on Freebox OS 4.11.1 and 4.13.1). Empty lists are serialized as {} by the box. | #### DHCPv6 Configuration API ##### Get the current DHCPv6 configuration ###### `GET /dhcpv6/config/` Returns the current DHCPv6Config Response `result`: DHCPv6Config Example request: ```http GET /api/v{version}/dhcpv6/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": true, "use_custom_dns": false, "dns": [ "2620:0:ccc::a", "2620:0:ccc::1" ] } } ``` ##### Update the current DHCPv6 configuration ###### `PUT /dhcpv6/config/` *permission `settings` (inferred)* Update the current DHCPv6Config Request body (`application/json`): DHCPv6Config Response `result`: DHCPv6Config Example request: ```http PUT /api/v{version}/dhcpv6/config/ HTTP/1.1 Host: mafreebox.freebox.fr { "use_custom_dns": true } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": true, "use_custom_dns": true, "dns": [ "2620:0:ccc::a", "2620:0:ccc::1" ] } } ``` ### Ftp The FTP API allow you to control the Freebox ftp server settings #### Ftp Errors When attempting to access the FTP API, you may encounter the following errors: | error_code | Description | | --- | --- | | internal_error | Internal error | | weak_password | Password is too weak for remote access | #### Ftp Config FtpConfig has the following attributes: ##### Object `FtpConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `enabled` | boolean | | is the FTP server enabled | | `allow_anonymous` | boolean | | can anonymous user log in | | `allow_anonymous_write` | boolean | | can anonymous user write data | | `username` | string | read-only | default user name to use. Cannot be changed | | `password` | string | write-only | user password | | `allow_remote_access` | boolean | | enable ftp server remote access NOTE: to be able to enable the remote access the password must be strong enough | | `weak_password` | boolean | read-only | is the ftp password weak (in this case remote access is disabled) | | `port_ctrl` | integer | | ftp control port to use for remote access | | `port_data` | integer | | ftp data port to use for remote access | | `remote_domain` | string | | domain name to use for remote access | #### Ftp config API ##### Get the current Ftp configuration ###### `GET /ftp/config/` Get the FtpConfig Response `result`: FtpConfig Example request: ```http GET /api/v{version}/ftp/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": false, "allow_anonymous": false, "allow_remote_access": false, "port_ctrl": 3615, "port_data": 1337, "weak_password": true, "allow_anonymous_write": false } } ``` ##### Update the FTP configuration ###### `PUT /ftp/config/` *permission `settings` (inferred)* Update the FtpConfig Request body (`application/json`): FtpConfig Response `result`: FtpConfig Example request: ```http PUT /api/v{version}/ftp/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "enabled": true } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": true, "allow_anonymous": false, "allow_anonymous_write": false } } ``` ### TFTP The TFTP API allow you to control the Freebox tftp server settings #### TFTP Errors When attempting to access the TFTP API, you may encounter the following errors: | error_code | Description | | --- | --- | | absolute | The path must be absolute | #### TFTP Config TftpConfig has the following attributes: ##### Object `TftpConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `enabled` | boolean | | is the TFTP server enabled | | `root` | string | | is the base64 encoded absolute path to the root directory exposed by the server. This path points to a folder inside the storage device (My Freebox). | #### TFTP Config API ##### Get the current TFTP configuration ###### `GET /tftp/config/` Get the TftpConfig Response `result`: TftpConfig Example request: ```http GET /api/v{version}/tftp/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": false, "root": "/ssd2" } } ``` ##### Update the TFTP configuration ###### `PUT /tftp/config/` *permission `settings` (inferred)* Update the TftpConfig Request body (`application/json`): TftpConfig Response `result`: TftpConfig Example request: ```http PUT /api/v{version}/tftp/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "enabled": true } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": true, "root": "/ssd2" } } ``` ### NAT With the nat API you control port forwarding on your network #### NAT Errors When attempting to access the LAN API, you may encounter the following errors: | error_code | Description | | --- | --- | | noent | Invalid id | | internal_error | Internal error | | exist | Conflict with an existing redirection | #### Dmz Config Dmz config has the following attributes: ##### Object `DmzConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `ip` | string | | dmz host IP | | `enabled` | boolean | | is dmz enabled | #### Dmz Config API ##### Get the current Dmz configuration ###### `GET /fw/dmz/` Returns the current DmzConfig Response `result`: DmzConfig Example request: ```http GET /api/v{version}/fw/dmz/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": false, "ip": "" } } ``` ##### Update the current Dmz configuration ###### `PUT /fw/dmz/` *permission `settings` (inferred)* Update the current LanConfig Request body (`application/json`): LanConfig Response `result`: LanConfig Example request: *The documentation example uses `PUT /lan/config/`, which differs from the operation path.* ```http PUT /api/v{version}/lan/config/ HTTP/1.1 Host: mafreebox.freebox.fr { "enabled": true, "ip": "192.168.1.42" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": true, "ip": "192.168.1.42" } } ``` ### Port Forwarding #### Port Forwarding Config Port forwarding config has the following attributes: ##### Object `PortForwardingConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | | forwarding id | | `enabled` | boolean | | is forwarding enabled | | `ip_proto` | string | | Values: `tcp` (TCP), `udp` (UDP). | | `wan_port_start` | integer | | forwarding range start **Correction:** Documented as string, returned as integer like wan_port_end (checked with GET /fw/redir/{id} on Freebox OS 4.11.1 and 4.13.1). | | `wan_port_end` | integer | | forwarding range end | | `lan_ip` | string | | forwarding target on LAN | | `lan_port` | integer | | forwarding target start port on LAN, (last port is lan_port + wan_port_end - wan_port_start) | | `hostname` | string | read-only | forwarding target host name | | `host` | LanHost | read-only | forwarding target host information (see: LanHost) | | `src_ip` | string | | if src_ip == 0.0.0.0 this rule will apply to any src ip otherwise it will only apply to the specified ip address | | `comment` | string | | comment | #### Port Forwarding API ##### Getting the list of port forwarding ###### `GET /fw/redir/` Response `result`: PortForwardingConfig[] Example request: ```http GET /api/v{version}/fw/redir/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "enabled": true, "comment": "", "id": 1, "host": {}, "hostname": "android-c5fe44a2c27be1e2", "lan_port": 69, "wan_port_end": 69, "wan_port_start": 69, "lan_ip": "192.168.1.22", "ip_proto": "tcp", "src_ip": "8.8.8.8" }, { "enabled": true, "comment": "", "id": 2, "host": {}, "hostname": "android-c5fe44a2c27be1e2", "lan_port": 1337, "wan_port_end": 1340, "wan_port_start": 1337, "lan_ip": "192.168.1.22", "ip_proto": "udp", "src_ip": "0.0.0.0" } ] } ``` ##### Getting a specific port forwarding ###### `GET /fw/redir/{redir_id}` Returns the requested PortForwardingConfig properties | Parameter | In | Type | Description | | --- | --- | --- | --- | | `redir_id` | path | integer | | Response `result`: PortForwardingConfig Example request: ```http GET /api/v{version}/fw/redir/1 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": true, "comment": "", "id": 1, "host": {}, "hostname": "android-c5fe44a2c27be1e2", "lan_port": 69, "wan_port_end": 69, "wan_port_start": 69, "lan_ip": "192.168.1.22", "ip_proto": "tcp", "src_ip": "0.0.0.0" } } ``` ##### Updating a port forwarding ###### `PUT /fw/redir/{redir_id}` *permission `settings` (inferred)* Update a PortForwardingConfig properties | Parameter | In | Type | Description | | --- | --- | --- | --- | | `redir_id` | path | integer | | Request body (`application/json`): PortForwardingConfig Response `result`: PortForwardingConfig Example request: ```http PUT /api/v{version}/fw/redir/1 HTTP/1.1 Host: mafreebox.freebox.fr { "enabled": false } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": false, "comment": "", "id": 1, "host": {}, "hostname": "android-c5fe44a2c27be1e2", "lan_port": 69, "wan_port_end": 69, "wan_port_start": 69, "lan_ip": "192.168.1.22", "ip_proto": "tcp", "src_ip": "0.0.0.0" } } ``` ##### Add a port forwarding ###### `POST /fw/redir/` *permission `settings` (inferred)* Create a PortForwardingConfig Request body (`application/json`): PortForwardingConfig Response `result`: PortForwardingConfig Example request: ```http POST /api/v{version}/fw/redir/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "enabled": true, "comment": "test", "lan_port": 4242, "wan_port_end": 4242, "wan_port_start": 4242, "lan_ip": "192.168.1.42", "ip_proto": "tcp", "src_ip": "0.0.0.0" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": true, "comment": "test", "id": 3, "host": {}, "hostname": "Mac-mini-de-Romain", "lan_port": 4242, "wan_port_end": 4242, "wan_port_start": 4242, "lan_ip": "192.168.1.42", "ip_proto": "tcp", "src_ip": "0.0.0.0" } } ``` ##### Delete a port forwarding ###### `DELETE /fw/redir/{redir_id}` *permission `settings` (inferred)* Delete a PortForwardingConfig | Parameter | In | Type | Description | | --- | --- | --- | --- | | `redir_id` | path | integer | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/fw/redir/3 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ### Incoming port configuration Some services hosted on the Freebox Server need to listen to public ip address port. Incoming port api allow to enable/disable incoming port binding, and select the bind port to prevent conflit with your own nat port forwarding rules. NOTE: you can’t add or remove incoming ports, this ports are managed by Freebox services. NOTE: in case of conflict with a nat port forwarding rule, this rule will have a higher priority and override the port forwarding rule. #### Incoming port Config Incoming port config has the following attributes: ##### Object `IncomingPortConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | string | read-only | incoming port id Documented values: `http` (http port for remote access to Freebox OS), `https` (https port for tls remote access to Freebox OS), `bittorrent-main` (main bittorrent port for Freebox downloader), `bittorrent-dht` (bittorrent port for DHT), `openvpn_routed` (routed openvpn port), `openvpn_bridge` (bridged openvpn port), `ipsec_ike` (ipsec ikev2 vpn port), `ipsec_nat` (ipsec nat vpn port), `pptp` (pptp vpn server port), `ftp` (ftp control port for FTP remote access), `ftp_pasv` (ftp data port for FTP remote access). | | `enabled` | boolean | | is the port binding allowed | | `active` | boolean | read-only | is the port binding currently active | | `type` | string | read-only | Values: `tcp` (TCP), `udp` (UDP), `tcp_udp` (both TCP and UDP). | | `in_port` | integer | | binding port | | `netns` | string | read-only | network namespace. The service may be running on a different namespace (for instance if the service uses the vpn client). | | `min_port` | integer | read-only | This field indicate the minimum possible value for in_port (see ConnectionStatus ipv4_port_range) | | `max_port` | integer | read-only | This field indicate the maximum possible value for in_port (see ConnectionStatus ipv4_port_range) | | `readonly` | boolean | read-only | If set to true, the in_port field cannot be changed because of the underlying protocol does not allow it | #### Incoming port API ##### Getting the list of incoming ports ###### `GET /fw/incoming/` Response `result`: IncomingPortConfig[] Example request: ```http GET /api/v{version}/fw/incoming/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "enabled": false, "type": "tcp", "in_port": 80, "id": "http", "netns": "init", "max_port": 65535, "min_port": 0 }, { "enabled": true, "type": "tcp", "in_port": 17591, "id": "bittorrent-main", "netns": "vpn", "max_port": 65535, "min_port": 0 }, { "enabled": true, "type": "udp", "in_port": 28946, "id": "bittorrent-dht", "netns": "vpn", "max_port": 65535, "min_port": 0 } ] } ``` ##### Getting a specific incoming port ###### `GET /fw/incoming/{port_id}` Returns the requested IncomingPortConfig properties | Parameter | In | Type | Description | | --- | --- | --- | --- | | `port_id` | path | string | | Response `result`: IncomingPortConfig Example request: ```http GET /api/v{version}/fw/incoming/bittorrent-main HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": true, "type": "tcp", "in_port": 17591, "id": "bittorrent-main", "netns": "vpn", "max_port": 65535, "min_port": 0 } } ``` ##### Updating an incoming port ###### `PUT /fw/incoming/{port_id}` *permission `settings` (inferred)* Update a IncomingPortConfig properties | Parameter | In | Type | Description | | --- | --- | --- | --- | | `port_id` | path | string | | Request body (`application/json`): IncomingPortConfig Response `result`: IncomingPortConfig Example request: *The documentation example uses `PUT /lan/fw/incoming/bittorrent-main`, which differs from the operation path.* ```http PUT /api/v{version}/lan/fw/incoming/bittorrent-main HTTP/1.1 Host: mafreebox.freebox.fr { "in_port": 3615 } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": true, "type": "tcp", "in_port": 3615, "id": "bittorrent-main", "netns": "vpn", "max_port": 65535, "min_port": 0 } } ``` ### UPnP IGD The UPnP IGD API allow you to control the settings of the Universal Plug n’ Play Internet Gateway Device service. This service allow hosts on your local network to manage nat redirections. #### UPnP IGD Errors When attempting to access the UPnP IGD API, you may encounter the following errors: | error_code | Description | | --- | --- | | disabled | the service is disabled | | noent | invalid rule id | #### UPnP IGD Config UPnPIGDConfig has the following attributes: ##### Object `UPnPIGDConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `enabled` | boolean | | is the UPnP IGD service enabled | | `version` | integer | | UPnP IGD protocol version Supported values are 1 / 2 | #### UPnP IGD config API ##### Get the current UPnP IGD configuration ###### `GET /upnpigd/config/` Get the UPnPIGDConfig Response `result`: UPnPIGDConfig Example request: ```http GET /api/v{version}/upnpigd/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": false, "version": 1 } } ``` ##### Update the UPnP IGD configuration ###### `PUT /upnpigd/config/` *permission `settings` (inferred)* Update the UPnPIGDConfig Request body (`application/json`): UPnPIGDConfig Response `result`: UPnPIGDConfig Example request: ```http PUT /api/v{version}/upnpigd/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "enabled": true, "version": 2 } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": true, "version": 2 } } ``` #### UPnP IGD Redirection UPnPRedir has the following attributes: ##### Object `UPnPRedir` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | string | read-only | the redirection id | | `enabled` | boolean | read-only | is the redirection enabled | | `ext_src_ip` | string | read-only | source IP | | `ext_port` | integer | read-only | external port | | `int_ip` | string | read-only | the target IP on your LAN | | `int_port` | integer | read-only | the target port on your LAN | | `proto` | string | read-only | the IP protocol to redirect | | `desc` | string | read-only | a description | | `remaining` | integer | read-only | seconds remaining before redirection expire | | `host` | LanHost | read-only | lan host if available | #### UPnP IGD Redirection API ##### Get the list of current redirection ###### `GET /upnpigd/redir/` Get the list of UPnPRedir redirections Response `result`: UPnPRedir[] Example request: ```http GET /api/v{version}/upnpigd/redir/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "enabled": true, "proto": "udp", "id": "0.0.0.0-53644-udp", "desc": "iC53644", "remaining": 0, "ext_src_ip": "0.0.0.0", "int_port": 16402, "int_ip": "192.168.1.44", "ext_port": 53644 } ] } ``` ##### Delete a redirection ###### `DELETE /upnpigd/redir/{id}` *permission `settings` (inferred)* Deletes the given UPnPRedir | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). Example request: *The documentation example uses `GET /upnpigd/redir/0.0.0.0-53644-udp`, which differs from the operation path.* ```http GET /api/v{version}/upnpigd/redir/0.0.0.0-53644-udp HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ### LCD The lcd API allow you to control the Freebox lcd screen settings #### LCD Errors When attempting to access the lcd API, you may encounter the following errors: | error_code | Description | | --- | --- | | inval | Invalid parameters | | no_panel | No screen detected | | setup | Unable to setup screen | | notsup | Operation is not supported | #### LCD Config LcdConfig has the following attributes: ##### Object `LcdConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `brightness` | integer | | the screen brightness (range from 0 to 100) | | `orientation_forced` | boolean | | is the screen orientation forced | | `orientation` | integer | | the screen orientation angle | | `hide_wifi_key` | boolean | | hide wifi key information (including qrcode) - optional | | `led_strip_enabled` | boolean | | enable/disable led strip brightness - optional | | `led_strip_brightness` | integer | | led strip brightness (range from 0 to 100) - optional | | `led_strip_animation` | string | | led strip animation - optional | | `available_led_strip_animations` | string[] | read-only | array containing what LED strip animations can be configured | | `hide_status_led` | boolean | | hide status LED (on supported Freebox models) - optional | | `screensaver` | string | | Configure the screensaver - optional Only present on boxes that have has_lcd_screensaver set to true in their SystemConfig information. Possible values are listed in the following table: Values: `disabled` (Display always on), `on` (Screensaver enabled), `night` (Screensaver enabled during the night). | #### LCD config API ##### Get the current LCD configuration ###### `GET /lcd/config/` Get the LcdConfig Response `result`: LcdConfig Example request: ```http GET /api/v{version}/lcd/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "brightness": 100, "orientation": 0, "orientation_forced": false, "hide_wifi_key": false, "hide_led": false } } ``` ##### Update the lcd configuration ###### `PUT /lcd/config/` *permission `settings` (inferred)* Update the LcdConfig Request body (`application/json`): LcdConfig Response `result`: LcdConfig Example request: ```http PUT /api/v{version}/lcd/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "brightness": 50 } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "brightness": 50, "orientation": 0, "orientation_forced": false, "hide_wifi_key": false, "hide_led": false } } ``` ### Ledstrip This API allows ledstrip scheduling on boxes that have has_led_strip to true in their `SystemConfig` information. #### Ledstrip errors When attempting to access the ledstrip API, you may encounter the following errors | error_code | Description | | --- | --- | | inval | Invalid parameters | #### Ledstrip planning object Ledstrip planning object have the following properties: ##### Object `LedstripPlanning` | Property | Type | Access | Description | | --- | --- | --- | --- | | `use_planning` | boolean | | is the planning enabled | | `planning_mode` | string | | current planning mode Values: `ledstrip_off` (ledstrip disabled). | | `resolution` | integer | read-only | planning resolution (number of slots per day) | | `mapping` | boolean[] | | mapping for planning : true or false mapping[0] is monday at 0:0 mapping[7 * resolution - 1] is sunday last slot (each slot has a duration of 60 * 24 / resolution minutes) The boolean value indicates whether the planning is in effect (i.e: ledstrip disabled) | #### Ledstrip status object Ledstrip status object has the following properties: ##### Object `LedstripStatus` | Property | Type | Access | Description | | --- | --- | --- | --- | | `use_planning` | boolean | read-only | is the planning enabled | | `next_change` | integer (unix-time) | read-only | UNIX timestamp (seconds) timestamp of the scheduled next change, according to planning | #### Ledstrip API ##### Get ledstrip status ###### `GET /ledstrip/status` Returns the Ledstrip status object Response `result`: { use_planning: boolean, next_change: integer } Example request: ```http GET /api/v{version}/ledstrip/status HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "use_planning": true, "next_change": 1651135474996 } } ``` ##### Get ledstrip planning Get the `LedstripPlanning` **Example request**: ```http GET /api/v{version}/ledstrip/planning/ HTTP/1.1 Host: mafreebox.freebox.fr ``` **Example response**: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```javascript { "success": true, "result": { "use_planning": false, "planning_mode": "ledstrip_off", "mapping": [ false, false, false, false, [ ... ] false, false, false, false ], "resolution": 48 } } ``` ##### Update ledstrip planning ###### `PUT /ledstrip/planning` *permission `settings` (inferred)* Request body (`application/json`): LedstripPlanning Response `result`: LedstripPlanning Example request: ```http PUT /api/v{version}/ledstrip/planning/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```javascript { "use_planning": true, "planning_mode": "ledstrip_off", "mapping": [ false, false, false, false, [ ... ], false, false, false, false ], "resolution": 48 } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```javascript { "success": true, "result": { "use_planning": false, "planning_mode": "ledstrip_off", "mapping": [ false, false, false, false, false, [ ... ] false, false, false, false ], "resolution": 48 } } ``` ### Network Share The network share API allow you to control the file sharing services running on the Freebox. #### Network Share Errors When attempting to access this API, you may encounter the following errors: | error_code | Description | | --- | --- | | invalid_workgroup_name | Invalid workgroup name | | invalid_logon_user | Invalid samba user name | | invalid_logon_password | Invalid samba user password | | invalid_afp_login_name | Invalid AFP user name | | invalid_afp_login_password | Invalid AFP user password | #### Samba Config SambaConfig has the following attributes: ##### Object `SambaConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `file_share_enabled` | boolean | | is file sharing enabled | | `print_share_enabled` | boolean | | is printer sharing enabled | | `logon_enabled` | boolean | | is login/password required to access shares | | `logon_user` | string | | samba user name | | `logon_password` | string | write-only | samba user password | | `workgroup` | string | | name of the workgroup | | `smbv2_enabled` | boolean | | Set to true to enable SMBv2/v3 | #### Samba config API ##### Get the current Samba configuration ###### `GET /netshare/samba/` Get the SambaConfig Response `result`: SambaConfig Example request: ```http GET /api/v{version}/netshare/samba/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "workgroup": "WORKGROUP", "print_share_enabled": true, "file_share_enabled": true, "logon_enabled": false, "logon_user": "freebox" } } ``` ##### Update the Samba configuration ###### `PUT /netshare/samba/` *permission `settings` (inferred)* Update the SambaConfig Request body (`application/json`): SambaConfig Response `result`: SambaConfig Example request: ```http PUT /api/v{version}/netshare/samba/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "print_share_enabled": false } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "workgroup": "WORKGROUP", "print_share_enabled": false, "file_share_enabled": true, "logon_enabled": false, "logon_user": "freebox" } } ``` #### Afp Config AfpConfig has the following attributes: ##### Object `AfpConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `enabled` | boolean | | is afp service enabled | | `guest_allow` | boolean | | allow guest to access shared files | | `server_type` | string | | Afp server type (to display proper icon) in MacOS valid server types are: Values: `powerbook`, `powermac`, `macmini`, `imac`, `macbook`, `macbookpro`, `macbookair`, `macpro`, `appletv`, `airport`, `xserve`. | | `login_name` | string | | Afp user name | | `login_password` | string | write-only | Afp user password | #### Afp config API ##### Get the current Afp configuration ###### `GET /netshare/afp/` Get the AfpConfig Response `result`: AfpConfig Example request: ```http GET /api/v{version}/netshare/afp/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": false, "guest_allow": true, "login_name": "freebox", "server_type": "airport" } } ``` ##### Update the Afp configuration ###### `PUT /netshare/afp/` *permission `settings` (inferred)* Update the AfpConfig Request body (`application/json`): AfpConfig Response `result`: AfpConfig Example request: ```http PUT /api/v{version}/netshare/afp/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "guest_allow": false } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": false, "guest_allow": false, "login_name": "freebox", "server_type": "airport" } } ``` ### UPnP AV The UPnP AV API allow you to control the settings of the Freebox UPnP AV service. #### UPnP AV Errors When attempting to access the UPnP AV API, you may encounter the following errors: | error_code | Description | | --- | --- | | internal_error | internal error | #### UPnP AV Config UPnPAVConfig has the following attributes: ##### Object `UPnPAVConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `enabled` | boolean | | is the UPnP AV service enabled | #### UPnP AV config API ##### Get the current UPnP AV configuration ###### `GET /upnpav/config/` Get the UPnPAVConfig Response `result`: UPnPAVConfig Example request: ```http GET /api/v{version}/upnpav/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": true } } ``` ##### Update the UPnP AV configuration ###### `PUT /upnpav/config/` *permission `settings` (inferred)* Update the UPnPAVConfig Request body (`application/json`): UPnPAVConfig Response `result`: UPnPAVConfig Example request: *The documentation example uses `PUT /upnpigd/config/`, which differs from the operation path.* ```http PUT /api/v{version}/upnpigd/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "enabled": false } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": false } } ``` ### Switch The Switch API allow you to control the settings of the Freebox integrated switch. #### Switch Errors When attempting to access the switch API, you may encounter the following errors: | error_code | Description | | --- | --- | | bad_port | invalid port number | | bad_speed | unable to set port speed | | bad_link | unable to set port link mode | | bad_mac_entry_type | invalid mac entry type | #### Switch Port Status Object SwitchPortStatus has the following attributes: ##### Object `SwitchPortStatus` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | read-only | switch port id | | `link` | string | read-only | Values: `up` (port is up), `down` (port is down). | | `duplex` | string | | Values: `half` (force in half duplex mode), `full` (force in full duplex mode), `auto`. **Correction:** Additional duplex value returned by current firmware (checked with GET /switch/status/ on Freebox OS 4.11.1 and 4.13.1). | | `speed` | string | | Values: `10` (10Base-T), `100` (100Base-TX), `1000` (1000Base-T), `2500`. **Correction:** Additional speed value returned by current firmware (checked with GET /switch/status/ on Freebox OS 4.11.1 and 4.13.1). | | `mode` | string | read-only | display form of speed and duplex mode | | `mac_list` | object[] | read-only | list of { mac, name } of hosts connected to this port | #### Switch Port Configuration Object SwitchPortConfig has the following attributes: ##### Object `SwitchPortConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | read-only | switch port id | | `duplex` | string | | Values: `auto` (auto negotiate duplex mode), `half` (force in half duplex mode), `full` (force in full duplex mode). | | `speed` | string | | Values: `auto` (auto negotiate speed), `10` (10Base-T), `100` (100Base-TX), `1000` (1000Base-T). | #### Switch Port Stats Object [UNSTABLE] SwitchPortStats has the following attributes: ##### Object `SwitchPortStats` | Property | Type | Access | Description | | --- | --- | --- | --- | | `rx_bad_bytes` | integer | read-only | | | `rx_broadcast_packets` | integer | read-only | | | `rx_bytes_rate` | integer | read-only | | | `rx_err_packets` | integer | read-only | | | `rx_fcs_packets` | integer | read-only | | | `rx_fragments_packets` | integer | read-only | | | `rx_good_bytes` | integer | read-only | | | `rx_good_packets` | integer | read-only | | | `rx_jabber_packets` | integer | read-only | | | `rx_multicast_packets` | integer | read-only | | | `rx_oversize_packets` | integer | read-only | | | `rx_packets_rate` | integer | read-only | | | `rx_pause` | integer | read-only | | | `rx_undersize_packets` | integer | read-only | | | `rx_unicast_packets` | integer | read-only | | | `tx_broadcast_packets` | integer | read-only | | | `tx_bytes` | integer | read-only | | | `tx_bytes_rate` | integer | read-only | | | `tx_collisions` | integer | read-only | | | `tx_deferred` | integer | read-only | | | `tx_excessive` | integer | read-only | | | `tx_fcs` | integer | read-only | | | `tx_late` | integer | read-only | | | `tx_multicast_packets` | integer | read-only | | | `tx_multiple` | integer | read-only | | | `tx_packets` | integer | read-only | | | `tx_packets_rate` | integer | read-only | | | `tx_pause` | integer | read-only | | | `tx_single` | integer | read-only | | | `tx_unicast_packets` | integer | read-only | | #### Switch API ##### Get the current switch status ###### `GET /switch/status/` Return the list of swith port status SwitchPortStatus Response `result`: SwitchPortStatus[] Example request: ```http GET /api/v{version}/switch/status/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "duplex": "half", "link": "down", "id": 3, "mode": "10BaseT-HD", "speed": "10" }, { "duplex": "full", "link": "up", "id": 1, "mode": "1000BaseT-FD", "speed": "1000" }, { "duplex": "half", "link": "down", "id": 2, "mode": "10BaseT-HD", "speed": "10" }, { "duplex": "full", "mac_list": [ { "mac": "00:24:D4:7E:00:4C", "hostname": "r0ro's player" } ], "link": "up", "id": 4, "mode": "1000BaseT-FD", "speed": "1000" } ] } ``` ##### Get a port configuration ###### `GET /switch/port/{id}` Get the SwitchPortConfig for the given port id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: SwitchPortConfig Example request: ```http GET /api/v{version}/switch/port/1 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "id": 1, "speed": "auto", "duplex": "auto" } } ``` ##### Update a port configuration ###### `PUT /switch/port/{id}` *permission `settings` (inferred)* Update the SwitchPortConfig for the given port id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Request body (`application/json`): SwitchPortConfig Response `result`: SwitchPortConfig Example request: ```http PUT /api/v{version}/switch/port/1 HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "speed": "10" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "id": 4, "speed": "10", "duplex": "auto" } } ``` ##### Get a port stats ###### `GET /switch/port/{id}/stats` Get the SwitchPortStats for the given port id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: SwitchPortStats Example request: ```http GET /api/v{version}/switch/port/4/stats HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "rx_packets_rate": 4, "rx_good_bytes": 20018805, "rx_oversize_packets": 0, "rx_unicast_packets": 113034, "tx_bytes_rate": 736, "tx_unicast_packets": 112409, "rx_bytes_rate": 608, "tx_packets": 166266, "tx_collisions": 0, "tx_packets_rate": 6, "tx_fcs": 0, "tx_bytes": 25316860, "rx_jabber_packets": 0, "tx_single": 0, "tx_excessive": 0, "rx_pause": 0, "rx_multicast_packets": 1217, "tx_pause": 0, "rx_good_packets": 114296, "rx_broadcast_packets": 45, "tx_multiple": 0, "tx_deferred": 0, "tx_late": 0, "tx_multicast_packets": 27962, "rx_fcs_packets": 0, "tx_broadcast_packets": 25895, "rx_err_packets": 0, "rx_fragments_packets": 0, "rx_bad_bytes": 0, "rx_undersize_packets": 0 } } ``` ### Wi-Fi The Wi-Fi API allow you to control the settings of the Freebox Wi-Fi. #### Wi-Fi Errors When attempting to access this API, you may encounter the following errors: | error_code | Description | | --- | --- | | inval | invalid parameters | | exist | entry already exists | | nospc | maximum entry count reached | | nodev | invalid device id | | noent | invalid id | | busy | device busy | | inval_band | invalid wifi band | | inval_ssid | invalid ssid | | inval_freq | invalid wifi frequency | | inval_cipher | invalid cipher mod | | inval_key_len | invalid key length | | inval_key | invalid key | | inval_ht_needs_wmm | wmm must be enabled for 802.11n | | inval_ac_needs_ht | invalid configuration 802.11ac need ht support | | inval_ac_not_2d4g | invalid configuration 802.11ac is not supported on 2.4G band | | inval_wps_needs_ccmp | wps need WPA2/AES to be enabled | | inval_wps_macfilter | wps cannot work when mac filter is enabled | | inval_wps_hidden_ssid | wps cannot work with hidden ssid | | inval_eht_needs_he | 802.11ax must be enabled for 802.11be | | inval_ht_needs_ht | 802.11n must be enabled for 802.11ax on 2.4G band | | inval_ht_needs_vht | 802.11ac must be enabled for 802.11ax on 6G band | | inval_6g_needs_he | 6G band requires 802.11ax | #### Wi-Fi Global Config Global config gives quick access to major configuration settings (eg: toggle Wi-Fi) WifiGlobalConfig has the following attributes: ##### Object `WifiGlobalConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `enabled` | boolean | | is wifi enabled | | `mac_filter_state` | string | | Values: `disabled` (mac filter is disabled), `whitelist` (mac filter is enabled, using a whitelist), `blacklist` (mac filter is enabled, using a blacklist). | #### Wi-Fi global config API ##### Get the current Wi-Fi global configuration ###### `GET /wifi/config/` Get the WifiGlobalConfig Response `result`: WifiGlobalConfig Example request: ```http GET /api/v{version}/wifi/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": true, "mac_filter_state": "blacklist" } } ``` ##### Update the Wi-Fi global configuration ###### `PUT /wifi/config/` *permission `settings` (inferred)* Update the WifiGlobalConfig Request body (`application/json`): WifiGlobalConfig Response `result`: WifiGlobalConfig Example request: ```http PUT /api/v{version}/wifi/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "enabled": false } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": false, "mac_filter_state": "blacklist" } } ``` #### Wi-Fi Steering Config WifiSteeringConfig has the following attributes: ##### Object `WifiSteeringConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `steering_level` | integer | | Wi-Fi steering level. Documented values: `0` (Wi-Fi steering is disabled), `1` (Devices are steered when they accept the change), `2` (Devices are steered more aggressively). | #### Wi-Fi steering config API ##### Get the current Wi-Fi steering configuration ###### `GET /wifi/steering/config/` Get the WifiSteeringConfig Response `result`: WifiSteeringConfig Example request: ```http GET /api/v{version}/wifi/steering/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "steering_level": 2 } } ``` ##### Update the Wi-Fi steering configuration ###### `PUT /wifi/steering/config/` *permission `settings` (inferred)* Update the WifiSteeringConfig Request body (`application/json`): WifiSteeringConfig Response `result`: WifiSteeringConfig Example request: ```http PUT /api/v{version}/wifi/steering/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "steering_level": 2 } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "steering_level": 2 } } ``` #### Wi-Fi global state ##### Wi-Fi global state object ###### Object `WifiGlobalState` | Property | Type | Access | Description | | --- | --- | --- | --- | | `state` | string | read-only | wifi global state Values: `enabled` (Wifi is enabled), `disabled` (Wi-Fi is disabled), `disabled_planning` (Wi-Fi is disabled by planning). | | `expected_phys` | ExpectedPhy[] | read-only | expected wifi cards | ###### Object `ExpectedPhy` | Property | Type | Access | Description | | --- | --- | --- | --- | | `band` | string | read-only | Values: `2d4g` (2.4GHz band), `5g` (5GHz band), `6g` (6 GHz band), `60g` (60GHz band). | | `phy_id` | integer | read-only | id of the phy | | `detected` | boolean | read-only | true if the wifi card is detected | ##### Wi-Fi global state API ###### Get the global wifi state ###### `GET /wifi/state/` Get the global wifi state WifiGlobalState Response `result`: WifiGlobalState (**Correction:** Documentation example shows an array, the box returns one object) Example request: ```http GET /api/v{version}/wifi/state/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "state": "enabled", "expected_phys": [ { "band": "2d4g", "phy_id": 0, "detected": true }, { "band": "5g", "phy_id": 1, "detected": true } ] } ] } ``` #### Wi-Fi Access Point ##### Wi-Fi AP objects The Freebox may have one or more access points, you can configure each access point with this api. ###### Object `WifiAp` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | read-only | wifi ap id | | `name` | string | read-only | wifi ap name | | `status` | WifiApStatus | read-only | ap status | | `capabilities` | WifiApCapabilities | read-only | ap capabilities | | `config` | WifiApConfig | | ap configuration | ###### Object `WifiApStatus` | Property | Type | Access | Description | | --- | --- | --- | --- | | `state` | string | read-only | Values: `scanning` (Ap is probing wifi channels), `no_param` (Ap is not configured), `bad_param` (Ap has an invalid configuration), `disabled` (Ap is permanently disabled), `disabled_planning` (Ap is currently disabled according to planning), `disabled_power_saving` (Ap is currently disabled according to power save), `disabled_temp` (Ap is currently disabled temporarily), `no_active_bss` (Ap has no active BSS), `starting` (Ap is stopping), `acs` (Ap is selecting the best available channel), `ht_scan` (Ap is scanning for other access point), `dfs` (Ap is performing dynamic frequency selection), `active` (Ap is active), `failed` (Ap has failed to start). | | `channel_width` | string | read-only | effective channel width (in MHz) **Correction:** Documented as int, returned as a string (checked with GET /wifi/ap/ on Freebox OS 4.11.1 and 4.13.1). | | `primary_channel` | integer | read-only | effective primary channel | | `secondary_channel` | integer | read-only | effective secondary channel | | `dfs_cac_remaining_time` | integer | read-only | time left in dfs state | | `dfs_disabled` | boolean | read-only | Indicates if DFS channels are unavailable regardless of how the WifiApConfig is configured for this phy. This is enabled when your freebox is in compatibility mode for other Freebox wifi products. | | `temp_disable_remaining_time` | integer | read-only | Optional remaining time this access point is temporarily disabled. | ###### Object `WifiApCapabilities` Capabilities per band (2d4g, 5g, 6g, 60g): a map of capability flags **Correction:** Documented as int per band, returned as an object of boolean flags per band (checked with GET /wifi/ap/ on Freebox OS 4.11.1 and 4.13.1). Type: map> NOTE: before enabling some feature in ap config, you should ensure that AP supports the feature using its provided capabilities. ###### Object `WifiApHtConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `ac_enabled` | boolean | | enable 802.11ac | | `ht_enabled` | boolean | | enable 802.11n [UNSTABLE] | ###### Object `WifiApHeConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `enabled` | boolean | | enable 802.11ax (HE) [UNSTABLE] | ###### Object `WifiApConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `band` | string | | Values: `2d4g` (2.4 GHz), `5g` (5 GHz), `6g` (6 GHz), `60g` (60 GHz). | | `channel_width` | string | | wanted channel width (in MHz) : 20 MHz 40 MHz 80 MHz 160 MHz Values: `20`, `40`, `80`, `160`, `320`. **Correction:** Documented as int, returned as a string; 320 MHz is the Wi-Fi 7 channel width (checked with GET /wifi/ap/ on Freebox OS 4.11.1 and 4.13.1). | | `primary_channel` | integer | | wanted primary channel, value of 0 means automatic selection | | `secondary_channel` | integer | | wanted secondary channel, value of 0 means automatic selection | | `dfs_enabled` | boolean | | enable channels that require DFS | | `ht` | WifiApHtConfig | | wifi ht config | | `he` | WifiApHeConfig | | wifi HE config | ###### Object `WifiApChannelSurveyData` | Property | Type | Access | Description | | --- | --- | --- | --- | | `timestamp` | integer | | timestamp at which the survey data was retrieved | | `busy_percent` | integer | | percentage of time the channel was sensed busy | | `tx_percent` | integer | | percentage of time spent sending on the channel | | `rx_percent` | integer | | percentage of time spent receiving Wi-Fi traffic on the channel | | `rx_bss_percent` | integer | | percentage of time spent receiving Wi-Fi traffic for a local BSS | ##### Wi-Fi AP API ###### Get the ap list ###### `GET /wifi/ap/` Get the list of Freebox Access Points WifiAp Response `result`: WifiAp[] Example request: ```http GET /api/v{version}/wifi/ap/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "capabilities": { "2d4g": { "shortgi20": true, "vht_rx_ldpc": false, "shortgi40": true }, "60g": {}, "5g": {} }, "name": "2.4G", "id": 0, "config": { "channel_width": "40", "ht": { "ht_enabled": true, "ac_enabled": false }, "dfs_enabled": false, "band": "2d4g", "secondary_channel": 13, "primary_channel": 9 }, "status": { "channel_width": "20", "primary_channel": 9, "dfs_cac_remaining_time": 0, "secondary_channel": 0, "state": "active" } } ] } ``` ###### Get a particular AP ###### `GET /wifi/ap/{id}` Get the WifiAp with the requested id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: WifiAp Example request: ```http GET /api/v{version}/wifi/ap/0 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "capabilities": { "2d4g": { "shortgi20": true, "vht_rx_ldpc": false, "shortgi40": true }, "60g": {}, "5g": {} }, "name": "2.4G", "id": 0, "config": { "channel_width": "40", "ht": { "ht_enabled": true, "ac_enabled": false }, "dfs_enabled": false, "band": "2d4g", "secondary_channel": 13, "primary_channel": 9 }, "status": { "channel_width": "20", "primary_channel": 9, "dfs_cac_remaining_time": 0, "secondary_channel": 0, "state": "active" } } } ``` ###### Update an AP ###### `PUT /wifi/ap/{id}` *permission `settings` (inferred)* Update the WifiAp | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Request body (`application/json`): WifiAp Response `result`: WifiAp Example request: ```http PUT /api/v{version}/wifi/ap/0 HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "config": { "channel_width": "20", "ht": { "ht_enabled": false }, "primary_channel": 0, "secondary_channel": 0 } } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "capabilities": [], "name": "2.4G", "id": 0, "config": { "channel_width": "20", "ht": { "ht_enabled": false, "ac_enabled": false }, "dfs_enabled": false, "band": "2d4g", "secondary_channel": 0, "primary_channel": 0 }, "status": { "channel_width": "20", "primary_channel": 0, "dfs_cac_remaining_time": 0, "secondary_channel": 0, "state": "scanning" } } } ``` ##### Wi-Fi AP allowed channels To be able to allow user to pick a valid channel combination for a given AP you should use the following api to retrieve the list of allowed channel combination. ###### Object `WifiAllowedComb` | Property | Type | Access | Description | | --- | --- | --- | --- | | `band` | string | read-only | the band for which the combination can be used Values: `2d4g` (2.4 GHz), `5g` (5 GHz), `60g` (60 GHz). | | `channel_width` | string | read-only | the channel_width for which the combination can be used | | `need_dfs` | boolean | read-only | does this combination requires DFS. You should only allow this combination if ap has allowed dfs. | | `dfs_cac_time` | integer | read-only | time required in dfs state before being able to start the AP. | | `psc` | boolean | read-only | is this using a PSC channel as primary. Some phones/PCs can only see 6GHz APs when their primary channel is a Preferred Scanning Channel (PSC). | | `primary` | integer | read-only | primary channel | | `secondary` | integer | read-only | secondary channel (zero means that secondary channel will not be used) | ###### `GET /wifi/ap/{id}/allowed_channel_comb` Get the WifiAllowedComb for the given ap id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: WifiAllowedComb[] Example request: ```http GET /api/v{version}/wifi/ap/0/allowed_channel_comb HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "channel_width": "20", "dfs_cac_time": 0, "need_dfs": false, "primary": 1, "band": "2d4g", "secondary": 0 }, { "channel_width": "20", "dfs_cac_time": 0, "need_dfs": false, "primary": 13, "band": "2d4g", "secondary": 0 }, { "channel_width": "40", "dfs_cac_time": 0, "need_dfs": false, "primary": 1, "band": "2d4g", "secondary": 5 }, { "channel_width": "40", "dfs_cac_time": 0, "need_dfs": false, "primary": 13, "band": "2d4g", "secondary": 9 } ] } ``` ##### Wi-Fi AP stations ###### Wi-Fi AP Stations objects WifiStation has the following attributes: ###### Object `WifiStation` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | string | read-only | station id | | `mac` | string | read-only | client MAC address | | `bssid` | string | read-only | bssid on which the client is associated | | `hostname` | string | read-only | client host name | | `host` | LanHost | read-only | client host information | | `state` | string | read-only | Values: `associated` (station is associated), `authenticated` (station is authenticated). | | `inactive` | integer | read-only | inactive duration (in seconds) | | `conn_duration` | integer | read-only | connection duration (in seconds) | | `rx_bytes` | integer | read-only | received bytes (from station to Freebox) | | `tx_bytes` | integer | read-only | transmitted bytes (from Freebox to station) | | `tx_rate` | integer | read-only | reception data rate (in bytes/s) | | `rx_rate` | integer | read-only | transmission data rate (in bytes/s) | | `signal` | integer | read-only | signal attenuation (in dB) | | `flags` | WifiStationFlags | read-only | station flags | | `last_rx` | WifiStationStats | read-only | last rx stats | | `last_tx` | WifiStationStats | read-only | last tx stats | ###### Object `WifiStationFlags` [UNSTABLE] | Property | Type | Access | Description | | --- | --- | --- | --- | | `legacy` | boolean | read-only | does station uses legacy wifi (802.11a, 802.11b) | | `ht` | boolean | read-only | does station support ht (802.11n) | | `vht` | boolean | read-only | does station support vht (802.11ac) | | `he` | boolean | read-only | does station support he (802.11ax) | | `authorized` | boolean | read-only | is the station authenticated | ###### Object `WifiStationStats` [UNSTABLE] | Property | Type | Access | Description | | --- | --- | --- | --- | | `bitrate` | integer | read-only | physical link rate (in 1/10th of MBit/s), -1 if unknown | | `mcs` | integer | read-only | current link mcs, -1 if not used | | `vht_mcs` | integer | read-only | current link vht mcs, -1 if not used | | `width` | string | read-only | current channel width | | `shortgi` | boolean | read-only | is shortgi enabled | ###### Get Wi-Fi Stations List ###### `GET /wifi/ap/{id}/stations/` Get the list of WifiStation associated to the AP | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: WifiStation[] Example request: ```http GET /api/v{version}/wifi/ap/0/stations/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "mac": "18:AF:36:15:69:42", "last_rx": { "bitrate": 110, "mcs": -1, "shortgi": false, "vht_mcs": -1, "width": "20" }, "tx_bytes": 2651, "last_tx": { "bitrate": 360, "mcs": -1, "shortgi": false, "vht_mcs": -1, "width": "20" }, "id": "00:24:D4:AC:DC:88-18:AF:36:15:69:42", "bssid": "00:24:D4:AC:DC:88", "flags": { "vht": false, "legacy": false, "authorized": true, "ht": false }, "tx_rate": 0, "host": {}, "inactive": 168, "conn_duration": 263, "hostname": "iPhone-de-r0ro", "state": "authenticated", "rx_bytes": 781, "rx_rate": 0, "signal": -38 } ] } ``` ###### Get Wi-Fi Station ###### `GET /wifi/ap/{id}/stations/{mac}` Get a WifiStation associated to the AP | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | | `mac` | path | string | | Response `result`: WifiStation Example request: ```http GET /api/v{version}/wifi/ap/0/stations/18:AF:36:15:69:42 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "mac": "18:AF:36:15:69:42", "last_rx": { "bitrate": 110, "mcs": -1, "shortgi": false, "vht_mcs": -1, "width": "20" }, "tx_bytes": 2651, "last_tx": { "bitrate": 360, "mcs": -1, "shortgi": false, "vht_mcs": -1, "width": "20" }, "id": "00:24:D4:AC:DC:88-18:AF:36:15:69:42", "bssid": "00:24:D4:AC:DC:88", "flags": { "vht": false, "legacy": false, "authorized": true, "ht": false }, "tx_rate": 0, "host": {}, "inactive": 168, "conn_duration": 263, "hostname": "iPhone-de-r0ro", "state": "authenticated", "rx_bytes": 781, "rx_rate": 0, "signal": -38 } } ``` ##### Wi-Fi AP channel survey history Retrieve survey data for the channel the AP is operating on, starting from a given timestamp. ###### Get survey data history ###### `GET /wifi/ap/{id}/channel_survey_history/{timestamp}` Get an array of WifiApChannelSurveyData | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | | `timestamp` | path | string | | Response `result`: WifiApChannelSurveyData[] Example request: ```http GET /api/v{version}/wifi/ap/0/channel_survey_history/1651135474000 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "busy_percent": 65, "tx_percent": 2, "timestamp": 1651135474996, "rx_bss_percent": 0, "rx_percent": 56 }, { "busy_percent": 70, "tx_percent": 3, "timestamp": 1651135475796, "rx_bss_percent": 0, "rx_percent": 58 }, { "busy_percent": 71, "tx_percent": 3, "timestamp": 1651135475896, "rx_bss_percent": 0, "rx_percent": 58 }, { "busy_percent": 73, "tx_percent": 4, "timestamp": 1651135475998, "rx_bss_percent": 0, "rx_percent": 59 } ] } ``` ##### Restart an AP **WARNING** during the restart the AP will be unavailable. You may not receive the response if you restart the Wifi card you are using to call the api This will restart an AP, this is useful when an AP is in failed state. This is the same as disabling/re-enabling the BSS on an AP. ###### `POST /wifi/ap/{id}/restart` *permission `settings` (inferred)* Restarts the AP | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http POST /api/v{version}/wifi/ap/0/restart HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` #### Wi-Fi BSS Each AP can manage a set of BSS, with this api you can manage BSS settings ##### Wi-Fi BSS objects ###### Object `WifiBss` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | string | read-only | BSSID (MAC address) **Correction:** Documented as int, the id is the BSSID (checked with GET /wifi/bss/ on Freebox OS 4.11.1 and 4.13.1). | | `phy_id` | integer | read-only | associated AP id **Correction:** Documented as string, returned as integer (WifiAp id) (checked with GET /wifi/bss/ on Freebox OS 4.11.1 and 4.13.1). | | `status` | WifiBssStatus | read-only | bss status | | `use_shared_params` | boolean | | if set to True the bss will use the shared parameters stored under shared_bss_params if not the bss will use a configuration specific to this bss stored under bss_params when you want to edit the bss config you should change the config values using values from bss_params or shared_bss_params as a source and update use_shared_params accordingly. | | `config` | WifiBssConfig | | bss configuration (use this field for editing) | | `bss_params` | WifiBssConfig | read-only | current configuration specific to this bss | | `shared_bss_params` | WifiBssConfig | read-only | current configuration for shared bss config | | `disable_wep` | boolean | read-only | Whether or not this BSS can work with wep encryption or not | ###### Object `WifiBssStatus` | Property | Type | Access | Description | | --- | --- | --- | --- | | `state` | string | read-only | Values: `phy_stopped` (associated AP is stopped), `no_param` (bss is missing config), `bad_param` (bss has an invalid config), `disabled` (bss is disabled), `temp_disabled` (bss has been temporary disabled), `starting` (bss is starting), `active` (bss is active), `failed` (bss has failed to start). | | `sta_count` | integer | read-only | number of stations for this bss | | `authorized_sta_count` | integer | read-only | number of authenticated stations for this bss | | `custom_key_ssid` | string | read-only | SSID to use with custom keys | | `is_main_bss` | boolean | deprecated | this as been replaced by use_shared_params in WifiBss | | `partners` | integer[] | read-only | The currently active MLO partners’s AP for this BSS. Can be empty if MLO is disabled. See the MLO chapter for more info | ###### Object `WifiBssConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `enabled` | boolean | | enable this BSS. Note that if you want the AP to completely stop emitting wifi you should use WifiGlobalConfig enabled attribute. | | `use_default_config` | boolean | deprecated | this as been replaced by use_shared_params in WifiBss | | `ssid` | string | | bss displayed name | | `hide_ssid` | boolean | | don’t show bss in bss list **Correction:** Declared str, returned as boolean (checked with GET /wifi/bss/ on Freebox OS 4.11.1 and 4.13.1). | | `gcmp256` | boolean | | Whether or not to use GCMP-256 (only in WPA3 & for box that supports 802.11-be) **Correction:** Declared str, returned as boolean (checked with GET /wifi/bss/ on Freebox OS 4.11.1 and 4.13.1). | | `encryption` | string | | Values: `wep` (wep (should not use)), `wpa_psk_auto` (wpa1 CCMP+TKIP (should not use)), `wpa_psk_tkip` (wpa1 TKIP (should not use)), `wpa_psk_ccmp` (wpa1 CCMP (should not use)), `wpa12_psk_auto` (wpa1+wpa2 CCMP+TKIP (should not use)), `wpa2_psk_auto` (wpa2 CCMP+TKIP (should not use)), `wpa2_psk_tkip` (wpa2 TKIP (should not use)), `wpa2_psk_ccmp` (wpa2 CCMP), `wpa23_psk_ccmp` (wpa2+wpa3 CCMP WPA3-personal transition mode), `wpa23_psk_ccmp_mrsno` (wpa2+wpa3 CCMP WPA3-personal compatibility mode), `wpa3_psk_ccmp` (wpa3 CCMP WPA3-personal only mode). | | `key` | string | | wifi key “****” will be returned when insufficient permission | | `eapol_version` | integer | read-only | eapol version | ##### Wi-Fi BSS API ###### Get the bss list ###### `GET /wifi/bss/` Get the list of Freebox Access Points WifiBss Response `result`: WifiBss[] Example request: ```http GET /api/v{version}/wifi/bss/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "id": "00:24:D4:AA:BB:CC", "phy_id": 0, "use_shared_params": false, "config": { "enabled": true, "ssid": "r0ro 2.4", "encryption": "wpa2_psk_ccmp", "use_default_config": false, "hide_ssid": false, "eapol_version": 2, "wps_enabled": true, "wps_uuid": "37f5c24a-4d8f-4dfc-9321-c40c42e588c0", "key": "jesaispasdevine!" }, "bss_params": { "enabled": true, "ssid": "r0ro 2.4", "encryption": "wpa2_psk_ccmp", "hide_ssid": false, "eapol_version": 2, "wps_enabled": true, "wps_uuid": "37f5c24a-4d8f-4dfc-9321-c40c42e588c0", "key": "jesaispasdevine!" }, "shared_bss_params": { "enabled": true, "ssid": "r0ro", "encryption": "wpa2_psk_ccmp", "hide_ssid": false, "eapol_version": 2, "wps_enabled": true, "wps_uuid": "37f5c24a-4d8f-4dfc-9321-c40c42e588c0", "key": "lav7lav7!" }, "status": { "state": "active", "sta_count": 1, "authorized_sta_count": 1, "is_main_bss": true } } ] } ``` ###### Get a particular BSS ###### `GET /wifi/bss/{id}` Get the WifiBss with the requested id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response `result`: WifiBss Example request: ```http GET /api/v{version}/wifi/bss/00:24:D4:AA:BB:CC HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "id": "00:24:D4:AA:BB:CC", "phy_id": 0, "use_shared_params": false, "config": { "enabled": true, "ssid": "r0ro 2.4", "encryption": "wpa2_psk_ccmp", "use_default_config": false, "hide_ssid": false, "eapol_version": 2, "wps_enabled": true, "wps_uuid": "37f5c24a-4d8f-4dfc-9321-c40c42e588c0", "key": "jesaispasdevine!" }, "bss_params": { "enabled": true, "ssid": "r0ro 2.4", "encryption": "wpa2_psk_ccmp", "hide_ssid": false, "eapol_version": 2, "wps_enabled": true, "wps_uuid": "37f5c24a-4d8f-4dfc-9321-c40c42e588c0", "key": "jesaispasdevine!" }, "shared_bss_params": { "enabled": true, "ssid": "r0ro", "encryption": "wpa2_psk_ccmp", "hide_ssid": false, "eapol_version": 2, "wps_enabled": true, "wps_uuid": "37f5c24a-4d8f-4dfc-9321-c40c42e588c0", "key": "lav7lav7!" }, "status": { "state": "active", "sta_count": 1, "authorized_sta_count": 1, "is_main_bss": true } } } ``` ###### Update an BSS ###### `PUT /wifi/bss/{id}` *permission `settings` (inferred)* Update the WifiAp | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Request body (`application/json`): WifiAp Response `result`: WifiBss Example request: *The documentation example uses `PUT /wifi//bss/00:24:D4:AA:BB:CC`, which differs from the operation path.* ```http PUT /api/v{version}/wifi//bss/00:24:D4:AA:BB:CC HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "config": { "key": "c'était trop facile" } } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "id": "00:24:D4:AA:BB:CC", "phy_id": 0, "use_shared_params": false, "config": { "enabled": true, "ssid": "r0ro 2.4", "encryption": "wpa2_psk_ccmp", "use_default_config": false, "hide_ssid": false, "eapol_version": 2, "wps_enabled": true, "wps_uuid": "37f5c24a-4d8f-4dfc-9321-c40c42e588c0", "key": "jesaispasdevine!" }, "bss_params": { "enabled": true, "ssid": "r0ro 2.4", "encryption": "wpa2_psk_ccmp", "hide_ssid": false, "eapol_version": 2, "wps_enabled": true, "wps_uuid": "37f5c24a-4d8f-4dfc-9321-c40c42e588c0", "key": "c'était trop facile" }, "shared_bss_params": { "enabled": true, "ssid": "r0ro", "encryption": "wpa2_psk_ccmp", "hide_ssid": false, "eapol_version": 2, "wps_enabled": true, "wps_uuid": "37f5c24a-4d8f-4dfc-9321-c40c42e588c0", "key": "lav7lav7!" }, "status": { "state": "active", "sta_count": 1, "authorized_sta_count": 1, "is_main_bss": true } } } ``` #### Wi-Fi Radar With this api you can list the surrounding Wi-Fi access points, and Wi-fi channel usage. This a new feature introduced in firmware 2.1.0 (api v2). A scan is automatically done at AP startup, if you need to refresh the information you can use the scan api ##### Wi-Fi Neighbor Object WifiNeighbor has the following attributes: ###### Object `WifiNeighbor` | Property | Type | Access | Description | | --- | --- | --- | --- | | `bssid` | string | read-only | neighbor bssid | | `ssid` | string | read-only | neighbor ssid | | `band` | string | read-only | the band for which the combination can be used Values: `2d4g` (2.4 GHz), `5g` (5 GHz), `60g` (60 GHz). | | `channel_width` | string | read-only | neighbor channel_width **Correction:** Documented as int, returned as a string (checked with GET /wifi/ap/{id}/neighbors/ on Freebox OS 4.11.1 and 4.13.1). | | `channel` | integer | read-only | neighbor primary channel | | `secondary_channel` | integer | read-only | neighbor secondary channel (0 for unused) | | `signal` | integer | read-only | signal attenuation in dB | | `capabilities` | WifiNeighborCap | read-only | neighbor capabilities | ###### Object `WifiNeighborCap` | Property | Type | Access | Description | | --- | --- | --- | --- | | `legacy` | boolean | read-only | neighbor uses legacy wifi (802.11a, 802.11b) | | `ht` | boolean | read-only | neighbor supports ht (802.11n) | | `vht` | boolean | read-only | neighbor supports vht (802.11ac) | ##### List AP neighbors ###### `GET /wifi/ap/{id}/neighbors/` Get the list of WifiNeighbor seen by the AP | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: WifiNeighbor[] Example request: ```http GET /api/v{version}/wifi/ap/0/neighbors/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "channel_width": "20", "capabilities": { "legacy": false, "vht": false, "ht": true }, "ssid": "Freebox-future", "channel": 1, "band": "2d4g", "bssid": "00:24:D4:BA:BB:EE", "secondary_channel": 0, "signal": -27 }, { "channel_width": "20", "capabilities": { "legacy": false, "vht": false, "ht": true }, "ssid": "Encore une freebox", "channel": 1, "band": "2d4g", "bssid": "F4:CA:E5:5E:AC:4F", "secondary_channel": 0, "signal": -33 }, { "channel_width": "20", "capabilities": { "legacy": false, "vht": false, "ht": true }, "ssid": "lav6-140c76670212", "channel": 1, "band": "2d4g", "bssid": "00:07:CB:00:00:FD", "secondary_channel": 0, "signal": -33 } ] } ``` ##### Wi-Fi Channel usage Object ###### Object `WifiChannelUsage` | Property | Type | Access | Description | | --- | --- | --- | --- | | `channel` | integer | read-only | channel number | | `band` | string | read-only | Values: `2d4g` (2.4 GHz), `5g` (5 GHz), `60g` (60 GHz). | | `noise_level` | integer | read-only | noise level on channel in dB | | `rx_busy_percent` | integer | read-only | rx channel busy time percentage | ##### List Wi-Fi channels usage ###### `GET /wifi/ap/{id}/channel_usage/` Get the list of WifiChannelUsage for the given AP | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: WifiChannelUsage[] Example request: ```http GET /api/v{version}/wifi/ap/0/channel_usage/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```text { "success": true, "result": "result": [ { "band": "2d4g", "noise_level": -66, "rx_busy_percent": 35, "channel": 1 }, [ ... ] { "band": "2d4g", "noise_level": -58, "rx_busy_percent": 46, "channel": 13 } ] } ``` ##### Refresh radar informations **WARNING** during the scan the AP will be unavailable. Therefore, you should ask for user confirmation prior to launching a scan. Once launched you should wait until the ap state comes back from scanning to get updated info. ###### `POST /wifi/ap/{id}/neighbors/scan` *permission `settings` (inferred)* Launch a wifi scan on given ap | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http POST /api/v{version}/wifi/ap/0/neighbors/scan HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` #### Wi-Fi Planning With api v2 you can now specify time range when you want to enable your wifi. ##### Wi-Fi Planning Object ###### Object `WifiPlanning` | Property | Type | Access | Description | | --- | --- | --- | --- | | `use_planning` | boolean | | is the planning enabled | | `resolution` | integer | read-only | planning resolution (number of slots per day) | | `mapping` | string[] | | mapping for planning : “on” or “off” mapping[0] is monday at 0:0 mapping[7 * resolution - 1] is sunday last slot (each slot has a duration of 60 * 24 / resolution minutes) | ##### Get Wi-Fi Planning ###### `GET /wifi/planning/` Get the current WifiPlanning Response `result`: WifiPlanning Example request: ```http GET /api/v{version}/wifi/planning/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "use_planning": false, "resolution": 48, "mapping": [ "on", "on", "on", "on", "on", "on", "on", "on" ] } } ``` ##### Update Wi-Fi Planning ###### `PUT /wifi/planning/` *permission `settings` (inferred)* Update the WifiPlanning Request body (`application/json`): WifiPlanning Response `result`: WifiPlanning Example request: ```http PUT /api/v{version}/wifi/planning/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "use_planning": true } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "use_planning": true, "resolution": 48, "mapping": [ "on", "on", "on", "on", "on", "on", "on", "on" ] } } ``` #### Wi-Fi MAC Filter API ##### Wi-Fi MAC Filter object WifiMacFilter has the following attributes: ###### Object `WifiMacFilter` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | string | read-only | filter id | | `mac` | string | read-only | MAC address to filter | | `comment` | string | | comment | | `type` | string | | Values: `whitelist` (if mac_filter is set to whitelist this station will be allowed), `blacklist` (if mac_filter is set to blacklist this station will be rejected). | | `hostname` | string | read-only | host name when available | | `host` | LanHost | read-only | host information when available | ##### Get the MAC filter list ###### `GET /wifi/mac_filter/` Get the list of WifiMacFilter Response `result`: WifiMacFilter[] Example request: ```http GET /api/v{version}/wifi/mac_filter/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "mac": "00:07:CB:01:02:03", "type": "whitelist", "comment": "test", "hostname": "00:07:CB:01:02:03", "id": "00:07:CB:01:02:03" }, { "mac": "00:24:D4:00:00:69", "type": "blacklist", "comment": "plop", "hostname": "r0ro's iPad", "id": "00:24:D4:00:00:69", "host": {} } ] } ``` ##### Getting a particular MAC filter ###### `GET /wifi/mac_filter/{filter_id}` Returns the requested WifiMacFilter properties | Parameter | In | Type | Description | | --- | --- | --- | --- | | `filter_id` | path | string | | Response `result`: WifiMacFilter Example request: ```http GET /api/v{version}/wifi/mac_filter/00:07:CB:01:02:03 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "mac": "00:07:CB:01:02:03", "type": "whitelist", "comment": "test", "hostname": "00:07:CB:01:02:03", "id": "00:07:CB:01:02:03" } } ``` ##### Updating a MAC filter ###### `PUT /wifi/mac_filter/{filter_id}` *permission `settings` (inferred)* Update a WifiMacFilter properties | Parameter | In | Type | Description | | --- | --- | --- | --- | | `filter_id` | path | string | | Request body (`application/json`): WifiMacFilter Response `result`: WifiMacFilter Example request: *The documentation example uses `PUT /wifi/mac_filter/`, which differs from the operation path.* ```http PUT /api/v{version}/wifi/mac_filter/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "comment": "filtre de test", "type": "blacklist" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "mac": "00:07:CB:01:02:03", "type": "blacklist", "comment": "filtre de test", "hostname": "00:07:CB:01:02:03", "id": "00:07:CB:01:02:03" } } ``` ##### Delete a MAC filter ###### `DELETE /wifi/mac_filter/{filter_id}` *permission `settings` (inferred)* Delete the WifiMacFilter with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `filter_id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/wifi/mac_filter/00:07:CB:01:02:03 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Create a new MAC filter ###### `POST /wifi/mac_filter/` *permission `settings` (inferred)* Crate a new the WifiMacFilter Request body (`application/json`): WifiMacFilter Response `result`: WifiMacFilter Example request: *The documentation example uses `POST /wifi/mac_filter/00:07:CB:01:02:03`, which differs from the operation path.* ```http POST /api/v{version}/wifi/mac_filter/00:07:CB:01:02:03 HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "comment": "filtre de test", "type": "blacklist", "mac": "00:07:CB:CB:07:00" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "mac": "00:07:CB:CB:07:00", "type": "blacklist", "comment": "filtre de test", "hostname": "00:07:CB:CB:07:00", "id": "00:07:CB:CB:07:00" } } ``` #### Wifi Config reset ##### Global reset You can reset Wifi to default configuration with this api ###### `POST /wifi/config/reset/` *permission `settings` (inferred)* Create a new the WifiMacFilter Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http POST /api/v{version}/wifi/config/reset/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Config reset value of an AP You can get the default config value of a given AP. ###### `GET /wifi/ap/{id}/default` Get the WifiApConfig with the requested id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: WifiApConfig Example request: ```http GET /api/v{version}/wifi/ap/0/default HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "channel_width": "20", "ht": {}, "dfs_enabled": false, "band": "2d4g", "secondary_channel": 0, "primary_channel": 0 } } ``` ##### Config reset value of a BSS You can get the default config value for a given BSS. ###### `GET /wifi/bss/{id}/default` Get the WifiBssConfig with the requested bssid | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response `result`: WifiBssConfig Example request: ```http GET /api/v{version}/wifi/bss/02:00:00:00:00:00/default HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": true, "wps_uuid": "7ace9cb4-3aec-486e-b487-28df4998ff46", "ssid": "super_ssid", "encryption": "wpa2_psk_ccmp", "wps_enabled": true, "hide_ssid": false, "eapol_version": 2, "key": "motdepasse" } } ``` ##### Config reset value (bulk) This api gets the same data as the per AP/BSS ones but in one call only ###### `GET /wifi/default` Get the WifiBssConfig or WifiApConfig of all cards Response `result`: { aps: { params: { channel_width: string, ht: object, dfs_enabled: boolean, band: string, secondary_channel: integer, primary_channel: integer }, ap_id: integer }[], bsss: { params: { enabled: boolean, wps_uuid: string, ssid: string, encryption: string, wps_enabled: boolean, hide_ssid: boolean, eapol_version: integer, key: string }, bssid: string }[] } Example request: ```http GET /api/v{version}/wifi/default HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "aps": [ { "params": { "channel_width": "20", "ht": {}, "dfs_enabled": false, "band": "2d4g", "secondary_channel": 0, "primary_channel": 0 }, "ap_id": 0 }, { "params": { "channel_width": "80", "ht": {}, "dfs_enabled": true, "band": "5g", "secondary_channel": 0, "primary_channel": 0 }, "ap_id": 1 } ], "bsss": [ { "params": { "enabled": true, "wps_uuid": "cbf5826c-25b2-4795-a7c7-cbd8f9454431", "ssid": "super_ssid", "encryption": "wpa2_psk_ccmp", "wps_enabled": true, "hide_ssid": false, "eapol_version": 2, "key": "lolzme" }, "bssid": "00:00:00:00:00:08" }, { "params": { "enabled": true, "wps_uuid": "1d77f4c0-9544-4478-a8f0-cccb77031b94", "ssid": "super_ssid", "encryption": "wpa2_psk_ccmp", "wps_enabled": true, "hide_ssid": false, "eapol_version": 2, "key": "lolzme" }, "bssid": "00:00:00:00:00:0C" } ] } } ``` #### Diagnostic API This API is intended to simplify detecting problems or suboptimal configs on bsss or aps. This API is articulated around the WifiDiagItem ##### Object `WifiDiagItem` | Property | Type | Access | Description | | --- | --- | --- | --- | | `ap_id` | integer | | When this item relates to an AP, this indicates the AP’s index When this item relates to a BSS, this field is unset | | `bssid` | string | | When this item relates to a BSS, this field indicates the bss’s id When this item relates to an AP, this field is unset | | `code` | string | | The code identifying which param is faulty/suboptimal Values: `all` (This is a the same as doing a full reset of this AP/BSS), `network_disabled` (This changes the ‘enabled’ field in WifiBssConfig), `network_security` (This changes the ‘encryption’ field in WifiBssConfig), `network_visibility` (This changes the ‘hide_ssid’ field in WifiBssConfig), `channel_width` (This changes the ‘channel_width’ field in WifiApConfig), `channel_value` (This changes the ‘channel’ & ‘secondary_channel’ fields in WifiApConfig). | | `severity` | string | | Values: `minor` (minor problems don’t have performance/compatibility implications), `major` (major problems do). | ##### Global diagnostic The global diagnostics evaluates/works on all AP/BSS at once. This is good for bulk access ###### `GET /wifi/diag` Get the WifiDiagItem for the box Response `result`: { aps: { severity: string, ap_id: integer, code: string }[], bsss: { severity: string, bssid: string, code: string }[] } Example request: ```http GET /api/v{version}/wifi/diag HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "aps": [ { "severity": "minor", "ap_id": 0, "code": "channel_width" }, { "severity": "major", "ap_id": 1, "code": "channel_value" } ], "bsss": [ { "severity": "major", "bssid": "02:00:00:00:00:08", "code": "network_security" }, { "severity": "major", "bssid": "02:00:00:00:00:0C", "code": "network_visibility" } ] } } ``` ###### `POST /wifi/diag` *permission `settings` (inferred)* Fix a few of the WifiDiagItem at once. ‘aps’ & ‘bsss’ are arrays in which you can put any items. You can also omit ‘aps’ and/or ‘bsss’ Response `result`: WifiDiagItem ##### Per AP/BSS diagnostic Same as the global API there also is a per AP/BSS api to get/fix the problems. ###### `GET /wifi/ap/{id}/diag` Get the WifiDiagItem for the AP/BSS | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: WifiDiagItem[] ###### `GET /wifi/bss/{id}/diag` Get the WifiDiagItem for the AP/BSS | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: WifiDiagItem[] Example request: *The documentation example uses `GET /wifi/ap/0/bss`, which differs from the operation path.* ```http GET /api/v{version}/wifi/ap/0/bss HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "severity": "minor", "ap_id": 0, "code": "channel_width" }, { "severity": "major", "ap_id": 0, "code": "channel_value" } ] } ``` ###### `POST /wifi/ap/{id}/diag` *permission `settings` (inferred)* Fix a few of the WifiDiagItem at once for a given AP/BSS | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response `result`: WifiDiagItem ###### `POST /wifi/bss/{id}/diag` *permission `settings` (inferred)* Fix a few of the WifiDiagItem at once for a given AP/BSS | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response `result`: WifiDiagItem #### Wifi WPS API This api lets you open wps sessions on wifi a bss to allow a device to connect to Wifi using WPS To be able to open wps session, you first need to make sure that the bss is properly configured (with `WifiBssConfig` field ‘wps_enabled’ set to true) Note that wps_enabled requires the encryption to either be wpa2_psk_ccmp or wpa2_psk_auto You should call the `WifiWpsCandidate` api help to check which bss can be used for wps Also, only one WPS session can be active at a given time ##### Wifi Wps Candidate object WifiWpsCandidate has the following attributes: ###### Object `WifiWpsCandidate` | Property | Type | Access | Description | | --- | --- | --- | --- | | `bssid` | string | read-only | bss id | | `ssid` | string | read-only | wifi network name | | `bss_uuid` | string | read-only | bss uuid for wps | | `band` | string | read-only | Documented values: `2d4g` (2.4 GHz), `5g` (5 GHz), `60g` (60 GHz). | | `encryption` | string | read-only | currently configured encryption mode see WifiBssConfig encryption field | | `wps_enabled` | boolean | read-only | is wps enabled for this bss | | `state` | string | read-only | the current state of the associated ap see WifiBssStatus state | ##### Enable/disable WPS on all Wi-Fi cards ###### `GET /wifi/wps/config/` Get the global WPS state. WPS is globally enabled if at least one BSS has WPS enabled. Response `result`: { enabled: boolean } Example request: ```http GET /api/v{version}/wifi/wps/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": true } } ``` ###### `PUT /wifi/wps/config/` *permission `settings` (inferred)* Set the global WPS state. It will update each BSS config with the provided state. Request body (`application/json`): { enabled: boolean } Response `result`: { enabled: boolean } Example request: ```http PUT /api/v{version}/wifi/wps/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "enabled": false } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": false } } ``` ##### Wifi WPS Session object WifiWpsSession has the following attributes: ###### Object `WifiWpsSession` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | read-only | wps session id | | `bss_uuid` | string | read-only | bss wps uuid | | `ssid` | string | read-only | ssid | | `active` | boolean | read-only | is the session active | | `result` | string | read-only | result of the wps session Values: `success` (success), `user_canceled` (canceled by user), `self_canceled` (canceled by restart of bss), `failed_timeout` (timeout while waiting for station), `failed_overlap` (another wps session was active), `failed_unknown` (unknown failure). | | `start_date` | integer | read-only | session start date (timestamp) | | `end_date` | integer (unix-time) | read-only | session end date (timestamp) **Correction:** Declared as enum without values, the prose describes a timestamp (checked with documentation on Freebox OS 4.11.1 and 4.13.1). | | `mac` | string | read-only | mac of the associated client (in case of success) | ##### Start a Wps session on a bss ###### `POST /wifi/wps/start/` *permission `settings` (inferred)* Once you identified a WifiWpsCandidate eligible for wps you can start a WifiWpsSession on the associated bss. In return you’ll get the id of the created session. Request body (`application/json`): WifiWpsCandidate Response `result`: integer Example request: ```http POST /api/v{version}/wifi/wps/start/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "bssid": "14:0C:76:87:04:38" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": 1 } ``` ##### Stop a Wps session This lets you close an open session **Example request**: ```http POST /api/v{version}/wifi/wps/stop/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "session_id": 1 } ``` **Example response**: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### List the Wps session ###### `GET /wifi/wps/sessions/` Get the list of WifiWpsSession Response `result`: WifiWpsSession[] Example request: ```http GET /api/v{version}/wifi/wps/sessions/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "mac": "00:00:00:00:00:00", "end_date": 1516012651, "ssid": "r0ro 5G", "active": false, "id": 1, "start_date": 1516012531, "result": "failed_timeout", "bss_uuid": "6a55ea3d-29fa-4bd9-b1e3-22a49a3ca134" } ] } ``` ##### Clear all Wps Sessions ###### `DELETE /wifi/wps/sessions/` *permission `settings` (inferred)* Clear all the existing wps sessions Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/wifi/wps/sessions/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` #### Wifi guest This api lets you create “custom key” (guest Wi-Fi access) that can be used on your existing bss to allow someone to connect to your Wi-Fi network without knowing your actual Wi-Fi password. When creating a “custom key” you can select if the associated access should be restricted to WAN only access, or if the guest can also access your local network. You can also define how long the access should be available. A dedicated Wi-Fi network is created for guest usage, and the SSID can be configured. Note that network will only be running when you have wifi running and a custom key created. ##### Wifi Custom Key config ###### Object `WifiCustomKeyConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `ssid` | string | | The name of the dedicated wifi network | | `ssid_read_only` | boolean | read-only | When true, the SSID name cannot be changed. | | `hide_ssid` | boolean | read-only | When true, the SSID used for guest network is hidden. | | `encryption` | string | read-only | Encryption used for guest Wi-Fi network. | ##### Get or change the dedicated ap config ###### `GET /wifi/custom_keys/config/` Get the dedicated guest config as a WifiCustomKeyConfig Response `result`: WifiCustomKeyConfig Example request: ```http GET /api/v{version}/wifi/custom_keys/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "ssid": "Freebox-C0001B-guest", "ssid_read_only": false, "hide_ssid": false, "encryption": "wpa2_psk" } } ``` ###### `PUT /wifi/custom_keys/config/` *permission `settings` (inferred)* Set the dedicated guest AP config. Only SSID or global enabled switch. Request body (`application/json`): { ssid: string } Response `result`: WifiCustomKeyConfig Example request: ```http PUT /api/v{version}/wifi/custom_keys/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "ssid": "my-guest-network-ssid" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "ssid": "my-guest-network-ssid", "ssid_read_only": true, "hide_ssid": false, "encryption": "wpa2_psk" } } ``` ##### Wifi Custom Key object WifiCustomKey has the following attributes: ###### Object `WifiCustomKeyHost` | Property | Type | Access | Description | | --- | --- | --- | --- | | `hostname` | string | read-only | host name | | `host` | LanHost | read-only | optional host information from Lan Browser (if available) | ###### Object `WifiCustomKeyParams` | Property | Type | Access | Description | | --- | --- | --- | --- | | `description` | string | | description of the custom key | | `key` | string | | Wi-Fi password for this custom access “****” will be returned when insufficient permission | | `max_use_count` | integer | | Number of different hosts that can connect to this network (maximum 127) 0 has special meaning, it means unlimited number of users. | | `duration` | integer | | Number of seconds before the custom access is revoked | | `access_type` | string | | Values: `full` (stations will get full access to local network + internet), `net_only` (stations connected using this custom key will be isolated and won’t have access to local network devices). | ###### Object `WifiCustomKey` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | read-only | custom key id | | `remaining` | integer | read-only | time remaining before the access (seconds) if 0 then it does not expire | | `params` | WifiCustomKeyParams | | custom key parameters | | `users` | WifiCustomKeyHost[] | read-only | list of hosts that used the custom key | ##### Get the list of wifi custom key ###### `GET /wifi/custom_key/` Get the list of WifiCustomKey Response `result`: WifiCustomKey[] Example request: ```http GET /api/v{version}/wifi/custom_key/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "id": 8, "remaining": 86376, "params": { "max_use_count": 100, "description": "soirée mario kart", "duration": 86400, "access_type": "full", "key": "YY5Sg74W3VNxrmfwAz7aCY7OVqRVG2JN" } } ] } ``` ##### Getting a particular wifi custom key ###### `GET /wifi/custom_key/{key_id}` Returns the requested WifiCustomKey properties | Parameter | In | Type | Description | | --- | --- | --- | --- | | `key_id` | path | integer | | Response `result`: WifiCustomKey Example request: ```http GET /api/v{version}/wifi/custom_key/8 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "id": 8, "remaining": 86376, "params": { "max_use_count": 100, "description": "soirée mario kart", "duration": 86400, "access_type": "full", "key": "YY5Sg74W3VNxrmfwAz7aCY7OVqRVG2JN" } } } ``` ##### Delete a wifi custom key ###### `DELETE /wifi/custom_key/{key_id}` *permission `settings` (inferred)* Delete the WifiCustomKey with the given id It will automatically disconnect any connected stations using this custom key | Parameter | In | Type | Description | | --- | --- | --- | --- | | `key_id` | path | integer | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/wifi/custom_key/8 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Create a new wifi custom key ###### `POST /wifi/custom_key/` *permission `settings` (inferred)* Create a new the WifiCustomKey Post the parameters of the custom key Request body (`application/json`): WifiCustomKey Response `result`: WifiCustomKey Example request: ```http POST /api/v{version}/wifi/custom_key HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "description": "zuper", "key": "rzR18eLeh6D8B7n1DtMbeDxwo2d4O9fB", "max_use_count": "100", "duration": 86400, "access_type": "net_only" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "id": 11, "remaining": 86399, "params": { "max_use_count": 100, "description": "zuper", "duration": 86400, "access_type": "full", "key": "rzR18eLeh6D8B7n1DtMbeDxwo2d4O9fB" } } } ``` #### Temporary disabling Wifi This API lets you disable some wifi bands for a given amount of time. This is useful to pair IOT devices that only supports some bands. ##### Temporary disable object TemporaryWifiDisable has the following attributes: ###### Object `TemporaryWifiDisable` | Property | Type | Access | Description | | --- | --- | --- | --- | | `duration` | integer | write-only | temporary disable duration | | `keep` | string | write-only | specify a wifi band to keep active Values: `2d4g` (keep only 2,4Ghz band active), `5g` (keep only 5GHz bands active), `6g` (keep only 6GHz band active). | | `remaining` | integer | read-only | remaining seconds the wifi is temporarily disabled. Set to 0 to stop the temporary wifi disabling period. | ##### Get temporary disable state ###### `GET /wifi/temp_disable` Get the state of temporary wifi disable. Response `result`: { remaining: integer } Example request: ```http GET /api/v{version}/wifi/temp_disable HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "remaining": 267 } } ``` ###### `POST /wifi/temp_disable` *permission `settings` (inferred)* Start or stop a temporary wifi disabling period Request body (`application/json`): { duration: integer, keep: string } Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http POST /api/v{version}/wifi/temp_disable HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "duration": 1200, "keep": "2d4g" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` #### Multi Link Operation (MLO) For a given BSS you can configure with which bands it will try to participate in an MLD. Whatever the configuration is, the operational state may be different if the BSS on the partner AP is unavailable (disabled or no EHT) or does not have the right parameters (not using shared params or wrong security) ##### Available partner To get the available AP partner of a BSS use the mlo/allowed_comb api to return a list of possible combinations: ###### `GET /wifi/bss/{id}/mlo/allowed_comb` Get the allowed phy combination for a BSS } | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http GET /api/v{version}/wifi/bss/02:00:00:00:00:00/mlo/allowed_comb HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```text ``` ##### MLO configuration object ###### Object `WifiMLOConfiguration` | Property | Type | Access | Description | | --- | --- | --- | --- | | `partners` | integer[] | | List of phys participating in the MLD for the BSS An empty array means MLO is disabled An array with only the BSS’s AP index in it means SLO (single link mode) The allowed combinations are retrieved by the mlo/allowed_comb api. | ##### Getting the MLO config To get the currently configured partners of a BSS mlo/config. It will return the current `WifiMLOConfiguration` for this BSS ###### `GET /wifi/bss/{id}/mlo/config` Get the current WifiMLOConfiguration for the BSS | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response `result`: WifiMLOConfiguration Example request: ```http GET /api/v{version}/wifi/bss/02:00:00:00:00:00/mlo/config HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "partners": [ 0, 1 ] } } ``` ##### Changing the MLO config To update the MLO confuguration put a new `WifiMLOConfiguration` at mlo/config. Please note that only combinations from mlo/allowed_comb can be used for the ‘partners’ field ###### `PUT /wifi/bss/{id}/mlo/config` *permission `settings` (inferred)* Update the WifiMLOConfiguration of a BSS. Only combinations from mlo/allowed_comb can be used for the partners field. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Request body (`application/json`): WifiMLOConfiguration Response `result`: WifiMLOConfiguration Example request: ```http PUT /api/v{version}/wifi/bss/02:00:00:00:00:00/mlo/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "partners": [ 0, 1 ] } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "partners": [ 0, 1 ] } } ``` ### System #### System Config SystemConfig has the following attributes: ##### Object `SystemConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `firmware_version` | string | read-only | freebox firmware version | | `mac` | string | read-only | freebox mac address | | `serial` | string | read-only | freebox serial number | | `uptime` | string | read-only | readable freebox uptime | | `uptime_val` | integer | read-only | freebox uptime (in seconds) | | `board_name` | string | read-only | freebox hardware revision | | `box_authenticated` | boolean | read-only | is the box authenticated (“étape 6”) | | `disk_status` | string | read-only | the internal disk status Values: `not_detected` (The disk as not been detected), `disabled` (The disk is disabled), `initializing` (The disk is initializing), `error` (The disk failed to mount), `active` (The disk is ready). | | `usb3_enable` | boolean | | enable USB3 (on supported platforms) | | `user_main_storage` | string | | The label of the storage partition to use for user data. (Matches the label of the DiskPartition) In case of ‘light’ box flavor, it must be set by to a permanently attached external storage | | `user_storage_powered` | boolean | read-only | Indicate whether the user storage is powered or not | | `expansions` | SystemConfigExpansion[] | read-only | List of expansions slots modules | | `model_info` | SystemModelInfo | read-only | Device informations | | `fans` | SystemConfigFan[] | read-only | List of fans on the system | ##### Object `SystemModelInfo` | Property | Type | Access | Description | | --- | --- | --- | --- | | `name` | string | read-only | Values: `fbxgw-r1/full` (Freebox Server (v6) revision 1), `fbxgw-r2/full` (Freebox Server (v6) revision 2), `fbxgw-r1/mini` (Freebox Mini revision 1), `fbxgw-r2/mini` (Freebox Mini revision 2), `fbxgw-r1/one` (Freebox One revision 1), `fbxgw-r2/one` (Freebox One revision 2), `fbxgw7-r1/full` (Freebox v7 revision 1), `fbxgw8-r1/full` (Freebox v8 revision 1), `fbxgw9-r1/full` (Freebox v9 revision 1), `fbxgw-r1`, `fbxgw-r2`, `fbxgw7-r1`, `fbxgw8-r1`, `fbxgw9-r1`. **Correction:** Boxes report their model without the /full, /mini or /one suffix (checked with GET /system/ on Freebox OS 4.11.1 and 4.13.1). | | `pretty_name` | string | read-only | Display name for the box model | | `has_expansions` | boolean | read-only | if present and true, the box has expansions | | `has_lan_sfp` | boolean | read-only | if present and true, the box has an SFP port for lan | | `has_dect` | boolean | read-only | if present and true, the box has a DECT base station | | `has_home_automation` | boolean | read-only | if present and true, the box has a Home automation module | | `has_femtocell_exp` | boolean | read-only | if present and true, the box has a femtocell expansion slot | | `has_fixed_femtocell` | boolean | read-only | if present and true, the box has an internal femtocell | | `has_vm` | boolean | read-only | if present and true, the box supports virtual machines | | `has_dsl` | boolean | read-only | if present and true, the box supports DSL | | `has_standby` | boolean | read-only | if present and true, the box supports standby | | `has_eco_wifi` | boolean | read-only | if present and true, the box supports Eco-WiFi | | `has_wop` | boolean | read-only | if present and true, the box supports Wake-On-PON | | `has_led_strip` | boolean | read-only | if present and true, the box has a LED strip | | `has_status_led` | boolean | read-only | if present and true, the box has a status LED | | `has_usb3_enable` | boolean | read-only | if present and true, the box supports disabling USB3 | | `has_lcd_screensaver` | any | read-only | if present and true, the box supports enabling a screensaver animation on its LCD display | ##### Object `SystemConfigSensor` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | string | read-only | sensor id | | `name` | string | read-only | sensor display name | | `value` | integer | read-only | sensor current value (in celsius degree) | ##### Object `SystemConfigFan` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | string | read-only | fan id | | `name` | string | read-only | fan display name | | `value` | integer | read-only | fan current speed (RPM) | ##### Object `SystemConfigExpansion` | Property | Type | Access | Description | | --- | --- | --- | --- | | `slot` | integer | read-only | expansion slot id | | `probe_done` | boolean | read-only | has the module presence been probed yet | | `present` | boolean | read-only | has an expansion module been detected in the slot | | `supported` | boolean | read-only | is the module supported in this slot | | `bundle` | string | read-only | module serial number | | `type` | string | read-only | module type Values: `unknown` (unknown module), `dsl_lte` (xDSL + LTE), `dsl_lte_external_antennas` (xDSL + LTE with external antennas switch), `ftth_p2p` (FTTH P2P), `ftth_pon` (FTTH PON), `security` (Security module). | #### System Config V5 (DEPRECATED) SystemConfigV5 has the following attributes: ##### Object `SystemConfigV5` | Property | Type | Access | Description | | --- | --- | --- | --- | | `firmware_version` | string | read-only | freebox firmware version | | `mac` | string | read-only | freebox mac address | | `serial` | string | read-only | freebox serial number | | `uptime` | string | read-only | readable freebox uptime | | `uptime_val` | integer | read-only | freebox uptime (in seconds) | | `board_name` | string | read-only | freebox hardware revision | | `temp_cpum` | integer | read-only | temp cpum (°C) | | `temp_sw` | integer | read-only | temp sw (°C) | | `temp_cpub` | integer | read-only | temp cpub (°C) | | `fan_rpm` | integer | read-only | fan rpm | | `box_authenticated` | boolean | read-only | is the box authenticated (“étape 6”) | | `disk_status` | string | read-only | the internal disk status Values: `not_detected` (The disk as not been detected), `disabled` (The disk is disabled), `initializing` (The disk is initializing), `error` (The disk failed to mount), `active` (The disk is ready). | | `box_flavor` | string | read-only | the box ‘flavor’ for a given model Values: `full` (The box has an internal storage), `light` (The box has no internal storage). | | `user_main_storage` | string | | The label of the storage partition to use for user data. (Matches the label of the DiskPartition) In case of ‘light’ box flavor, it must be set by to a permanently attached external storage | #### System API ##### Get the current system info [UNSTABLE] ###### Current version (api >= v6) ###### `GET /system/` *unstable* Get the SystemConfig Response `result`: SystemConfig Example request: ```http GET /api/v{version}/system/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "mac": "34:27:92:60:0B:9E", "sensors": [ { "id": "t2", "name": "Température 2", "value": 47 }, { "id": "t1", "name": "Température 1", "value": 45 }, { "id": "t3", "name": "Température 3", "value": 42 }, { "id": "cpu_cp_slave", "name": "Température CPU CP Slave", "value": 72 }, { "id": "cpu_cp_master", "name": "Température CPU CP Master", "value": 72 }, { "id": "cpu_ap", "name": "Température CPU", "value": 64 } ], "model_info": { "pretty_name": "Freebox v7 (r1)", "has_expansions": true, "name": "fbxgw7-r1/full", "has_lan_sfp": true, "has_dect": true, "internal_hdd_size": 0, "has_home_automation": true, "wifi_type": "2d4_5g_5g" }, "fans": [ { "id": "secondary-fan", "name": "Ventilateur 2", "value": 1725 }, { "id": "main", "name": "Ventilateur 1", "value": 1739 } ], "expansions": [ { "type": "security", "present": true, "slot": 1, "probe_done": true, "supported": true, "bundle": "985700J183900112" }, { "type": "ftth_p2p", "present": true, "slot": 2, "probe_done": true, "supported": true, "bundle": "959300V181500003" } ], "box_authenticated": true, "disk_status": "active", "uptime": "2 heures 11 minutes 32 secondes", "uptime_val": 7892, "user_main_storage": "Disque 1", "board_name": "fbxgw7r", "serial": "957601J183400107", "firmware_version": "6.6.6" } } ``` ###### Old version (api < v5) ###### `GET /api/v8/system/` Get the `SystemConfigV5` Example request: ```http GET /api/v{version}/system/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "mac": "F4:CA:E5:5C:EA:14", "box_flavor": "light", "temp_cpub": 63, "disk_status": "active", "box_authenticated": true, "board_name": "fbxgw1r", "fan_rpm": 1832, "temp_sw": 52, "uptime": "6 jours 22 heures 9 minutes 46 secondes", "uptime_val": 598186, "user_main_storage": "Disque 1", "temp_cpum": 62, "serial": "805400T144100853", "firmware_version": "6.6.6" } } ``` ##### Reboot the system ###### `POST /system/reboot/` *permission `settings` (inferred)* Reboot the Freebox Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http POST /api/v{version}/system/reboot/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Shutdown the system ###### `POST /system/shutdown/` *permission `settings` (inferred)* Shutdown the Freebox Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http POST /api/v{version}/system/shutdown/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ### VPN Server [UNSTABLE] The VPN Server API allows you to control the Freebox VPN Server #### VPN Server Errors When attempting to access this API, you may encounter the following errors: | error_code | Description | | --- | --- | | inval | invalid parameters | | exist | entry already exists | | noent | invalid id | | nomem | internal error | | unsupp | not supported | | inuse | resource in use | | busy | resource is busy | | ioerror | internal error | | size | too many elements | #### VPN Server List ##### VPN Server Object ###### Object `VPNServer` VPNServer has the following attributes: | Property | Type | Access | Description | | --- | --- | --- | --- | | `name` | string | read-only | VPN server name (id) | | `type` | string | read-only | VPN server type Values: `ipsec` (IPsec IKEv2 server), `pptp` (PPTP VPN server), `openvpn` (OpenVPN server), `wireguard` (WireGuard server). | | `state` | string | read-only | server state Values: `stopped`, `starting`, `started`, `stopping`, `error`. | | `connection_count` | integer | read-only | number of active connections | | `auth_connection_count` | integer | read-only | number of active connections that have passed authentication | ##### VPN Server List API ###### `GET /vpn/` *unstable* Get the list of VPNServer Response `result`: VPNServer[] Example request: ```http GET /api/v{version}/vpn/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "state": "stopped", "type": "pptp", "name": "pptp", "connection_count": 0, "auth_connection_count": 0 }, { "state": "stopped", "type": "openvpn", "name": "openvpn_routed", "connection_count": 0, "auth_connection_count": 0 }, { "state": "stopped", "type": "openvpn", "name": "openvpn_bridge", "connection_count": 0, "auth_connection_count": 0 }, { "state": "stopped", "type": "wireguard", "name": "wireguard", "connection_count": 0, "auth_connection_count": 0 } ] } ``` #### VPN Server Config ##### Object `VPNPPTPConfig` VPNServerConfig has the following attributes: | Property | Type | Access | Description | | --- | --- | --- | --- | | `mppe` | string | | Values: `disable` (disable mppe), `require` (require mppe), `require_128` (require 128 bits mppe). | | `allowed_auth` | object | | allowed authentication methods dictionnary with following entries: pap chap mschapv2 values are booleans. | ##### Object `VPNOpenVpnConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `cipher` | string | | Values: `blowfish`, `aes128`, `aes256`, `chacha20poly1305`. | | `disable_fragment` | boolean | | disable fragment configuration option | | `use_tcp` | boolean | | use TCP instead of UDP | ##### Object `VPNWireGuardConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `mtu` | integer | | wireguard device MTU. Value must be between 512 and 1420. | ##### Object `VPNIPSecAuthMode` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id_source` | string | | source of the connection id Values: `custom`. | | `id_custom` | string | | value of the source id when id_source is custom | ##### Object `VPNIPSecConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `ike_version` | integer | read-only | IKE protocol version | | `auth_modes` | VPNIPSecAuthMode[] | read-only | map of supported auth modes, currently only psk is supported | ##### Object `VPNServerConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | string | read-only | VPN server id | | `type` | string | read-only | VPN server type Values: `pptp` (PPTP VPN server), `openvpn` (OpenVPN server), `ipsec` (IPsec IKEv2 server), `wireguard` (WireGuard server). | | `enabled` | boolean | | is the VPN server enabled | | `enable_ipv4` | boolean | | enable IPv4 on this server NOTE: Not relevant for openvpn_bridge, pptp and wireguard | | `enable_ipv6` | boolean | | enable IPv6 on this server NOTE: Not relevant for openvpn_bridge, pptp and wireguard | | `port` | integer | | the server port NOTE: you can only edit the server port when type is openvpn or wireguard | | `min_port` | integer | read-only | This field indicate the minimum possible value for port (see ConnectionStatus ipv4_port_range) | | `max_port` | integer | read-only | This field indicate the maximum possible value for port (see ConnectionStatus ipv4_port_range) | | `port_ike` | integer | | IPSec ike server port NOTE: only present for ipsec server | | `port_nat` | integer | | IPSec nat server port NOTE: only present for ipsec server | | `conf_pptp` | VPNPPTPConfig | | only available when type is PPTP | | `conf_openvpn` | VPNOpenVpnConfig | | only available when type is OpenVPN | | `conf_ipsec` | VPNIPSecConfig | | only available when type is IPsec | | `conf_wireguard` | VPNWireGuardConfig | | only available when type is WireGuard | | `ip_start` | string | read-only | start of the IP range that will be used to give clients an IP | | `ip_end` | string | read-only | end of the IP range that will be used to give clients an IP | | `ip6_start` | string | read-only | start of the IPv6 range that will be used to give clients an IPv6 | | `ip6_end` | string | read-only | end of the IPv6 range that will be used to give clients an IPv6 | #### VPN Server Config API ##### Get a VPN config ###### `GET /vpn/{vpn_id}/config/` *unstable* Get the VPNServerConfig | Parameter | In | Type | Description | | --- | --- | --- | --- | | `vpn_id` | path | string | | Response `result`: VPNServerConfig Example request: ```http GET /api/v{version}/vpn/openvpn_routed/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": false, "port": 1194, "conf_openvpn": { "cipher": "aes128" }, "id": "openvpn_routed", "ip_start": "192.168.27.65", "ip_end": "192.168.27.95", "type": "openvpn" } } ``` ##### Update the VPN configuration ###### `PUT /vpn/openvpn_routed/config/` *permission `settings` (inferred) · unstable* Update the VPNServerConfig Request body (`application/json`): VPNServerConfig Response `result`: VPNServerConfig Example request: ```http PUT /api/v{version}/vpn/openvpn_routed/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "conf_openvpn": { "cipher": "blowfish" } } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": false, "port": 1194, "conf_openvpn": { "cipher": "blowfish" }, "id": "openvpn_routed", "ip_start": "192.168.27.65", "ip_end": "192.168.27.95", "type": "openvpn" } } ``` #### VPN Server User API VPN users are common to all VPN servers. ##### VPN Server User Object ###### Object `VPNUser` VPNUser has the following attributes: | Property | Type | Access | Description | | --- | --- | --- | --- | | `login` | string | | VPN user login | | `type` | string | | VPN user type Values: `standard`, `wireguard`. | | `password` | string | write-only | VPN user password (length must be between 8 and 32) | | `password_set` | boolean | read-only | True if a password was provided for this user | | `ip_reservation` | string (ipv4) | | You can specify the IP you want to assign to this user. If you don’t want to use a specific IP pass an empty string or omit this property. This field is required if the type property is set to ‘wireguard’. The IP must be in the VPN range (see ip_start, ip_end). | ###### Object `conf_wireguard` This field is present only if the type property is set to ‘wireguard’. | Property | Type | Access | Description | | --- | --- | --- | --- | | `keepalive` | integer | | Interval in seconds at which keepalive packets are sent. | | `psk` | boolean | | Enable optional preshared-key. | ##### VPN Server User List ###### `GET /vpn/user/` *unstable* Get the list of VPNUser Response `result`: VPNUser[] Example request: ```http GET /api/v{version}/vpn/user/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "ip_reservation": "", "type": "standard", "login": "test-1392677633-np", "password_set": false }, { "ip_reservation": "", "type": "standard", "login": "test-1392677633", "password_set": true }, { "ip_reservation": "192.168.27.68", "type": "wireguard", "login": "test-1392677633-wg", "password_set": false, "conf_wireguard": { "keepalive": 10, "psk": false } } ] } ``` ##### Get a VPN user ###### `GET /vpn/user/{login}` *unstable* Gets the VPNUser with the given login | Parameter | In | Type | Description | | --- | --- | --- | --- | | `login` | path | string | | Response `result`: VPNUser Example request: ```http GET /api/v{version}/vpn/user/test-1392677633-np HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "ip_reservation": "", "login": "test-1392677633-np", "type": "standard", "password_set": false } } ``` ##### Add a VPN User ###### `POST /vpn/user/` *permission `settings` (inferred) · unstable* Creates a new VPNUser. Request body (`application/json`): VPNUser Response `result`: VPNUser Example request: ```http POST /api/v{version}/vpn/user/ HTTP/1.1 Host: mafreebox.freebox.fr { "login": "vpnuser01", "type": "standard", "password": "thisisasecret", "ip_reservation": "192.168.27.69" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "ip_reservation": "192.168.27.69", "login": "vpnuser01", "password_set": true } } ``` ##### Delete a VPN User ###### `DELETE /vpn/user/{login}` *permission `settings` (inferred) · unstable* Deletes the VPNUser | Parameter | In | Type | Description | | --- | --- | --- | --- | | `login` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/vpn/user/vpnuser01 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Update a VPN User ###### `PUT /vpn/user/{login}` *permission `settings` (inferred) · unstable* Updates the VPNUser task with the given login | Parameter | In | Type | Description | | --- | --- | --- | --- | | `login` | path | string | | Request body (`application/json`): VPNUser Response `result`: VPNUser Example request: ```http PUT /api/v{version}/vpn/user/test-1392677633-np HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "password": "donttellanyone" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "ip_reservation": "", "login": "test-1392677633-np", "password_set": true } } ``` #### VPN IP Pool ##### Get the VPN server IP pool reservations ###### `GET /vpn/ip_pool/` *unstable* Gets the VPNUser with the given login Response `result`: { ip_start: string, ip_end: string, reservations: { login: string, ip: string }[] } Example request: ```http GET /api/v{version}/vpn/ip_pool/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "ip_start": "192.168.27.65", "ip_end": "192.168.27.95", "reservations": [ { "login": "test", "ip": "192.168.27.69" } ] } } ``` #### VPN Server Connection API This API allows listing the active connections to the VPN server ##### VPN Connection Object ###### Object `VPNConnection` VPNConnection has the following attributes: | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | string | read-only | connection id | | `vpn` | string | read-only | related VPN server id | | `user` | string | read-only | user login | | `authenticated` | boolean | read-only | is the connection authenticated | | `auth_time` | integer | read-only | timestamp of the authentication | | `src_ip` | string (ipv4) | read-only | connection source IP address | | `src_port` | integer | read-only | connection source port | | `local_ip` | string (ipv4) | read-only | attributed IP address from VPN adress pool **Correction:** Declared int, returned as a dotted IPv4 string (as in the doc example) (checked with GET /vpn/connection/ on Freebox OS 4.11.1 and 4.13.1). | | `rx_bytes` | integer | read-only | rx bytes | | `tx_bytes` | integer | read-only | tx bytes | ##### Get the list of connections ###### `GET /vpn/connection/` *unstable* Get the list of VPNUser Response `result`: VPNConnection[] Example request: *The documentation example uses `GET /vpn/user/`, which differs from the operation path.* ```http GET /api/v{version}/vpn/user/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "rx_bytes": 94, "authenticated": true, "tx_bytes": 94, "user": "test", "id": "pptp-2", "vpn": "pptp", "src_ip": "93.184.216.119", "auth_time": 1392895603, "local_ip": "192.168.27.65" } ] } ``` ##### Close a given connection ###### `DELETE /vpn/connection/{id}` *permission `settings` (inferred) · unstable* Deletes the VPNUser | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/vpn/connection/pptp-2 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` #### VPN User configuration file API For OpenVPN and WireGuard servers, you can download a configuration file that will be used to configure the VPN client ##### Donwload a user configuration file ###### `GET /vpn/download_config/{server_name}/{login}/{fmt}` *permission `settings` · unstable · side effect: Each download regenerates the OpenVPN configuration and invalidates the previous one* Download an configuration file for the given server and login The “fmt” field must be set to either “plain” or “json”. WARNING: each time you download a new OpenVPN configuration file for a given user, you invalidate previous configuration file emitted for this user WARNING: This api will not be available if you are missing the ‘settings’ permission | Parameter | In | Type | Description | | --- | --- | --- | --- | | `server_name` | path | string | | | `login` | path | string | | | `fmt` | path | string | Values: `plain`, `json`. | Response: `application/x-openvpn-profile` or `application/json` Example request: ```http GET /api/v{version}/vpn/download_config/openvpn_routed/test/plain HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Date: Thu, 20 Feb 2014 13:14:01 GMT Server: nginx Content-Type: application/x-openvpn-profile Content-Disposition: attachment; filename="config_openvpn_routed_test.ovpn" Keep-Alive: timeout=5, max=99 Connection: Keep-Alive Transfer-Encoding: chunked [ ... ] ``` ### VPN Client [UNSTABLE] The VPN Client API allows you to control the Freebox VPN Client #### VPN Client Errors When attempting to access this API, you may encounter the following errors: | error_code | Description | | --- | --- | | inval | invalid parameters | | nomem | internal error | | ioerror | internal error | | nodev | invalid device | | noent | invalid id | | netdown | network is not available | | exist | entry already exists | | busy | resource is busy | #### VPN Client Configuration ##### VPN Client Configuration Object ###### Object `VPNClientConfig` VPNClientConfig has the following attributes: | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | string | read-only | VPN config id | | `description` | string | | VPN description | | `type` | string | | VPN server type Values: `pptp` (PPTP VPN server), `openvpn` (OpenVPN server), `wireguard` (WireGuard server). | | `active` | boolean | | is this configuration active. Only one configuration is active at a time. | | `conf_pptp` | VPNClientConfigPPTP | | only available when type is PPTP | | `conf_wireguard` | VPNClientConfigWireGuard | | only available when type is WireGuard | ###### Object `VPNClientConfigPPTP` VPNClientConfigPPTP has the following attributes: | Property | Type | Access | Description | | --- | --- | --- | --- | | `remote_host` | string | | remote host IP or name | | `username` | string | | VPN username | | `password` | string | write-only | VPN password | | `mppe` | string | | Values: `disable` (disable mppe), `require` (require mppe), `require_128` (require 128 bits mppe). | | `allowed_auth` | object | | allowed authentication methods dictionary with following keys: eap pap chap mschap mschapv2 values are booleans. | ###### Object `VPNClientConfigWireGuard` VPNClientConfigWireGuard has the following attributes: | Property | Type | Access | Description | | --- | --- | --- | --- | | `remote_addr` | string | | remote host IP | | `remote_port` | integer | | remote host port | | `remote_public_key` | string | | remote host public key | | `remote_preshared_key` | string | | optional preshared key | | `local_priv_key` | string | | local private key | | `local_addr` | VPNClientConfigWireGuardIP[] | | IPs to assign to the local interface. | | `dns` | string[] | | list of strings containing IPs of DNS servers to use. Both IPv4 and IPv6 are supported. | ###### Object `VPNClientConfigWireGuardIP` | Property | Type | Access | Description | | --- | --- | --- | --- | | `ip` | string | | string representation of an IPv4 or IPv6 address | | `len` | integer | | prefix length associated with the IP address | ##### Get VPN Client configuration list ###### `GET /vpn_client/config/` *unstable* Get the list of VPNClientConfig Response `result`: VPNClientConfig[] Example request: ```http GET /api/v{version}/vpn_client/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "type": "pptp", "description": "test vpn2", "active": true, "id": "vpn0", "conf_pptp": { "mppe": "require", "username": "freeuser", "remote_host": "vpnhost.example.org", "allowed_auth": { "eap": false, "mschap": false, "mschapv2": true, "chap": false, "pap": false } } }, { "type": "pptp", "description": "test vpn1", "active": false, "id": "vpn1", "conf_pptp": { "mppe": "require", "username": "testuser", "remote_host": "example.org", "allowed_auth": { "eap": false, "mschap": false, "mschapv2": true, "chap": false, "pap": false } } }, { "type": "wireguard", "description": "test vpn2", "active": false, "id": "vpn2", "conf_wireguard": { "local_addr": [ { "ip": "198.51.100.10", "len": 24 } ], "local_priv_key": "TdbS1Y0RHZ6rRNSxlEUssD/pnRDfrHMFfJPLl5icvQg=", "dns": [ "198.51.100.53", "2001:db8:100::53" ], "mtu": 1420, "remote_public_key": "QZnLR0TYPbPbhfVWeLVRf1zsPC0JXG/woVmsmEkgsw8=", "remote_addr": "192.0.2.1", "remote_port": 51820, "remote_preshared_key": "" } } ] } ``` ##### Get a VPN client config ###### `GET /vpn_client/config/{id}` *unstable* Get the VPNClientConfig | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response `result`: VPNClientConfig Example request: ```http GET /api/v{version}/vpn_client/config/vpn0 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "type": "pptp", "description": "test vpn2", "active": true, "id": "vpn0", "conf_pptp": { "mppe": "require", "username": "freeuser", "remote_host": "vpnhost.example.org", "allowed_auth": { "eap": false, "mschap": false, "mschapv2": true, "chap": false, "pap": false } } } } ``` ##### Add a VPN client configuration ###### `POST /vpn_client/config/` *permission `settings` (inferred) · unstable* Creates a new VPNClientConfig. Request body (`application/json`): VPNClientConfig Response `result`: VPNClientConfig Example request: ```http POST /api/v{version}/vpn_client/config/ HTTP/1.1 Host: mafreebox.freebox.fr { "type": "pptp", "description": "test pptp", "active": false, "conf_pptp": { "mppe": "require", "username": "fbxtest", "password": "", "remote_host": "test.example.org", "allowed_auth": { "mschapv2": true } } } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "type": "pptp", "description": "test pptp", "active": false, "id": "vpn2", "conf_pptp": { "password": "", "mppe": "require", "username": "fbxtest", "remote_host": "test.example.org", "allowed_auth": { "eap": false, "mschap": false, "mschapv2": true, "chap": false, "pap": false } } } } ``` ##### Delete a VPN client Configuration ###### `DELETE /vpn_client/config/{id}` *permission `settings` (inferred) · unstable* Deletes the VPNClientConfig | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/vpn_client/config/vpn2 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Update the VPN client configuration ###### `PUT /vpn_client/config/{id}` *permission `settings` (inferred) · unstable* Update the VPNServerConfig | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Request body (`application/json`): VPNServerConfig Response `result`: VPNServerConfig Example request: ```http PUT /api/v{version}/vpn_client/config/vpn0 HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "active": false } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "type": "pptp", "description": "test vpn2", "active": false, "id": "vpn0", "conf_pptp": { "mppe": "require", "username": "freeuser", "remote_host": "vpnhost.example.org", "allowed_auth": { "eap": false, "mschap": false, "mschapv2": true, "chap": false, "pap": false } } } } ``` #### VPN Client Status ##### VPN Client Status Object ###### Object `VPNClientStatus` VPNClientStatus has the following attributes: | Property | Type | Access | Description | | --- | --- | --- | --- | | `enabled` | boolean | read-only | is VPN client enabled | | `active_vpn` | string | read-only | active VPN id | | `active_vpn_description` | string | read-only | active VPN description | | `type` | string | read-only | active VPN type Values: `pptp` (PPTP VPN server), `openvpn` (OpenVPN server), `wireguard` (WireGuard server). | | `state` | string | read-only | Values: `waiting_wan` (waiting for wan connection), `going_up` (connecting), `up` (connected), `going_down` (disconnecting), `down` (disconnected). | | `last_up` | integer | read-only | timestamp of last successful connection | | `last_try` | integer | read-only | timestamp of last connection attempt | | `next_try` | integer | read-only | seconds left until next connection attempt | | `last_error` | string | read-only | Values: `none` (no error), `internal` (internal error), `authentication_failed` (wrong credentials), `auth_failed` (wrong credentials), `resolv_failed` (invalid host name), `connect_timeout` (connection timeout), `connect_failed` (connection failed), `setup_control_failed` (PPTP session negotiation failure), `setup_call_failed` (PPTP session failure), `protocol` (protocol error), `remote_terminated` (connection closed by remote peer), `remote_disconnect` (connection closed by remote peer). | | `stats` | VpnClientStats | read-only | connection statistics | | `IPv4` | VpnClientIpInfo | read-only | connection IPv4 information | ###### Object `VpnClientStats` | Property | Type | Access | Description | | --- | --- | --- | --- | | `rate_up` | integer | read-only | current upload rate (in byte/s) | | `rate_down` | integer | read-only | current download rate (in byte/s) | | `bytes_up` | integer | read-only | total bytes uploaded | | `bytes_down` | integer | read-only | total bytes downloaded | ###### Object `VpnClientIpInfo` | Property | Type | Access | Description | | --- | --- | --- | --- | | `config_valid` | boolean | read-only | is the configuration valid | | `ip_mask` | object | read-only | assigned IP and netmask | | `domain` | string | read-only | provided domain | | `gateway` | string (ipv4) | read-only | provided gateway | | `dns` | (string (ipv4))[] | read-only | list of dns servers | | `provider` | string | read-only | ip_mask source Values: `none` (none), `static` (static IP configuration), `ppp` (ppp), `dhcp` (DHCP server). | | `routes` | any[] | read-only | list of provided routes | | `dhcp` | object | read-only | DHCP status information | ##### Get the VPN client status ###### `GET /vpn_client/status` *unstable* Get the VPNClientStatus Response `result`: VPNClientStatus Example request: ```http GET /api/v{version}/vpn_client/status HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "enabled": true, "type": "pptp", "last_error": "none", "active_vpn_description": "test vpn", "last_try": 1392904509, "state": "up", "stats": { "rate_up": 0, "bytes_down": 94, "bytes_up": 94, "rate_down": 0 }, "active_vpn": "vpn1", "next_try": 0, "last_up": 1392904510, "ipv4": { "routes": {}, "config_valid": true, "ip_mask": { "ip": "192.168.27.65", "mask": "255.255.255.255" }, "provider": "ppp", "dhcp": { "state": "down", "renew_remaining": 0, "dhcp_options": {}, "lease_remaining": 0, "lease_time": 0, "rebind_remaining": 0, "server_id": 0 }, "dns": [ "212.27.38.253" ], "domain": "", "gateway": "212.27.38.253" } } } ``` ##### Get the VPN client logs ###### `GET /vpn_client/log` *unstable* Response `result`: string Example request: ```http GET /api/v{version}/vpn_client/log HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": "2014-02-20 14:55:10 dbg: ppp: pppd: sent [ ... ] " } ``` ## Diagnostics ### Slowness The slowness API allow you to execute diagnostics on a selected host to detect a potential causes of degradation of the throughput. #### Slowness Errors When attempting to access this API, you may encounter the following errors: | error_code | Description | | --- | --- | | inval | invalid parameters | | nodev | invalid device id | | nohost | invalid host GID or not found | | noconn | WAN connection is down | | netdown | link with host is down | | erunning | API is already running | | internal | system internal error | #### Slowness API ##### Get the last result of a given host ## Downloads ### Download With the download API you can control the download queue of the Freebox. The Freebox supports downloads from HTTP, FTP, Magnet link, `.torrent` files and newsgroups (NNTP). Each download task is represented by a `Download` object. #### Download Errors When attempting to access the download API, you may encounter the following errors: | error_code | Description | | --- | --- | | task_not_found | No task was found with the given id | | invalid_operation | Attempt to perform an invalid operation | | invalid_file | Error with the download file (invalid format ?) | | invalid_url | URL is invalid | | not_implemented | Method not implemented | | out_of_memory | No more memory available to perform the requested action | | invalid_task_type | The task type is invalid | | hibernating | The downloader is hibernating | | need_bt_stopped_done | This action is only valid for Bittorrent task in stopped or done state | | bt_tracker_not_found | Attempt to access an invalid tracker object | | too_many_tasks | Too many tasks | | invalid_address | Invalid peer address | | port_conflict | Port conflict when setting config | | invalid_priority | Invalid priority | | internal_error | Internal error | | ctx_file_error | Failed to initialize task context file (need to check disk) | | exists | Same task already exists | | port_outside_range | Incoming port is not available for this customer (see `ConnectionStatus` ipv4_port_range) | #### Download Task / TaskFile Errors Each download task can encounter one of the following errors: | Error | Description | | --- | --- | | none | No error | | internal | Internal error | | disk_full | The disk is full | | unknown | Unknown error | | parse_error | Parse error | | http_301 | HTTP 301 error | | http_400 | HTTP 400 error | | http_401 | | | http_402 | | | http_403 | | | http_404 | | | http_405 | | | http_406 | | | http_407 | | | http_408 | | | http_409 | | | http_410 | | | http_411 | | | http_412 | [ … ] | | http_413 | | | http_414 | | | http_415 | | | http_416 | | | http_417 | | | http_422 | | | http_423 | | | http_424 | | | http_425 | | | http_426 | | | http_427 | | | http_428 | | | http_429 | | | http_430 | | | http_431 | | | http_4xx | Other 4xx HTTP errors | | http_500 | HTTP 500 error | | http_501 | | | http_502 | | | http_503 | | | http_504 | | | http_505 | | | http_506 | [ … ] | | http_507 | | | http_508 | | | http_509 | | | http_510 | | | http_511 | | | http_5xx | Other 5xx HTTP errors | | http_redirections_exceeded | Too many HTTP redirections | | nzb_no_group | Cannot find the requested group on server | | nzb_not_found | Article not fount on the server | | nzb_invalid_crc | Invalid article CRC | | nzb_invalid_size | Invalid article size | | nzb_invalid_filename | Invalid filename | | nzb_open_failed | Error opening | | nzb_write_failed | Error writing | | nzb_missing_size | Missing article size | | nzb_decode_error | Article decoding error | | nzb_missing_segments | Missing article segments | | nzb_error | Other nzb error | | unknown_host | Unknown host | | timeout | Timeout | | bad_authentication | Invalid credentials | | connection_refused | Remote host refused connection | | nzb_authentication_required | Nzb server need authentication | | bt_tracker_error | Unable to announce on tracker | | bt_missing_files | Missing torrent files | | bt_file_error | Error accessing torrent files | | missing_ctx_file | Error accessing task context file | #### Download object Download objects have the following attributes: ##### Object `Download` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | read-only | id | | `type` | string | read-only | The valid download types are: Values: `bt` (bittorrent download), `nzb` (newsgroup download), `http` (HTTP download), `ftp` (FTP download). | | `name` | string | read-only | | | `status` | string | | The valid download status are: Values: `stopped` (task is stopped, can be resumed by setting the status to downloading), `queued` (task will start when a new download slot is available the queue position is stored in queue_pos attribute), `starting` (task is preparing to start download), `downloading`, `stopping` (task is gracefully stopping), `error` (there was a problem with the download, you can get an error code in the error field), `done` (the download is over. For bt you can resume seeding setting the status to seeding if the ratio is not reached yet), `checking` ((only valid for nzb) download is over, the downloaded files are being checked using par2), `repairing` ((only valid for nzb) download is over, the downloaded files are being repaired using par2), `extracting` ((only valid for nzb) download is over, the downloaded files are being extracted), `seeding` ((only valid for bt) download is over, the content is Change to being shared to other users. The task will automatically stop once the seed ratio has been reached), `retry` (You can set a task status to ‘retry’ to restart the download task.). | | `size` | integer | read-only | download size (in Bytes) | | `queue_pos` | integer | | position in download queue (0 if not queued) | | `io_priority` | string | | The valid download priorities are: Values: `low` (low), `normal` (normal), `high` (high). | | `tx_bytes` | integer | read-only | transmitted bytes (including protocol overhead) | | `rx_bytes` | integer | read-only | received bytes (including protocol overhead) | | `tx_rate` | integer | read-only | current transmit rate (in byte/s) | | `rx_rate` | integer | read-only | current receive rate (in byte/s) | | `tx_pct` | integer | read-only | transmit percentage (without protocol overhead) To improve precision the value as been scaled by 100 so that a tx_pct of 123 means 1.23% | | `rx_pct` | integer | read-only | received percentage (without protocol overhead) To improve precision the value as been scaled by 100 so that a tx_pct of 123 means 1.23% | | `error` | string | read-only | An error code | | `created_ts` | integer (unix-time) | read-only | UNIX timestamp (seconds) timestamp of the download creation time | | `eta` | integer | read-only | estimated remaining download time (in seconds) | | `download_dir` | string | read-only | directory where the file(s) will be saved (base64 encoded) | | `stop_ratio` | integer | read-only | Only relevant for bittorrent tasks. Once the transmit ration has been reached the task will stop seeding. The ratio is scaled by 100 to improve resolution. A stop_ratio of 150 means that the task will stop seeding once tx_bytes = 1.5 * rx_bytes. | | `archive_password` | string | | (only relevant for nzb) password for extracting downloaded archives | | `info_hash` | string | | (only relevant for bt) torrent info_hash encoded in hexa | | `piece_length` | integer | | (only relevant for bt) torrent piece length in bytes | #### Download API ##### Retrieve a Download task ###### `GET /downloads/` *permission `downloader` (inferred)* Returns the collection of all Download tasks Response `result`: Download Example request: ```http GET /api/v{version}/downloads/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "rx_bytes": 147450, "tx_bytes": 3460, "download_dir": "L0Rpc3F1ZSBkdXIvVMOpbMOpY2hhcmdlbWVudHMv", "archive_password": "", "eta": 60290, "status": "downloading", "io_priority": "normal", "type": "bt", "piece_length": 524288, "queue_pos": 2, "id": 1273, "info_hash": "A7055D06E5A8F7F816EC01AC7F7F5243D3CB008F", "created_ts": 1485513882, "stop_ratio": 150, "tx_rate": 202, "name": "debian-8.7.1-amd64-CD-1.iso", "tx_pct": 0, "rx_pct": 0, "rx_rate": 10950, "error": "none", "size": 660600000 } } ``` ###### `GET /downloads/{id}` *permission `downloader` (inferred)* Returns the Download task with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: Download Example request: ```http GET /api/v{version}/downloads/16 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "rx_bytes": 688005364, "tx_bytes": 3232055279, "download_dir": "L0Rpc3F1ZSBkdXIvVMOpbMOpY2hhcmdlbWVudHMv", "archive_password": "", "eta": 331896, "status": "seeding", "io_priority": "high", "size": 678428672, "type": "bt", "error": "none", "queue_pos": 0, "id": 14, "created_ts": 1349786169, "tx_rate": 0, "name": "debian-6.0.6-amd64-CD-1.iso", "rx_pct": 10000, "rx_rate": 0, "tx_pct": 0 } } ``` ##### Delete a Download task ###### `DELETE /downloads/{id}` *permission `downloader` (inferred)* Deletes the Download task with the given id, without erasing the downloaded files If the task was not done it is stopped You can call this method to remove done tasks from the task list. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/downloads/16 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ###### `DELETE /downloads/{id}/erase` *permission `downloader` (inferred)* Same as previous, but erases the downloaded files | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). ##### Update a Download task ###### `PUT /downloads/{id}` *permission `downloader` (inferred)* Updates the Download task with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Request body (`application/json`): Download Response `result`: Download Example request: ```http PUT /api/v{version}/downloads/16 HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "io_priority": "high", "status": "stopped" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "rx_bytes": 683407058, "tx_bytes": 17866436, "download_dir": "L0Rpc3F1ZSBkdXIvVMOpbMOpY2hhcmdlbWVudHMv", "eta": 1075260392, "status": "stopping", "io_priority": "high", "size": 678428672, "type": "bt", "error": "none", "queue_pos": 0, "id": 14, "created_ts": 1349786169, "tx_rate": 0, "name": "debian-6.0.6-amd64-CD-1.iso", "stop_ratio": 55936, "rx_pct": 10000, "rx_rate": 0, "tx_pct": 4 } } ``` ##### Get download log ###### `GET /downloads/{id}/log` *permission `downloader` (inferred)* Get the log. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: string Example request: ```http GET /api/v{version}/downloads/16/log HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": "log line\nanother log line\n" } ``` ##### Adding a new Download task ###### Adding by URL Supported URL scheme are `http://`, `ftp://`, `magnet:` You can start a recursive download by setting the recursive parameter. The downloader will then extract links from each donwloaded html page and continue downloading files on the same domain and on the same root path. This can be used to download all the files on a directory index. You can add multiple downloads at once by passing a list of URL (separated by a new line delimiter) in download_url_list instead of using download_url. /!NOTE: for this API the request arguments must be encoded using “application/x-www-form-urlencoded” (or “multipart/form-data” for file upload) instead of “application/json” ###### `POST /downloads/add` *permission `downloader` (inferred)* **Adding by URL** NOTE: instead of passing password and username you can include them in the URL. On success you’ll get the id of the new download task. On success you’ll get the list of id of the new download tasks. **Adding by file upload** Request body (`application/x-www-form-urlencoded`): { download_url: string, download_url_list: string, download_dir: string, filename: string, hash: string, recursive: boolean, username: string, password: string, archive_password: string, cookies: string } Request body (`multipart/form-data`): { download_file: binary (application/octet-stream), download_dir: string, archive_password: string } Response `result`: { id: integer | integer[] } or { id: integer } Example request : Single download add: ```http POST /api/v{version}/downloads/add HTTP/1.1 Host: mafreebox.freebox.fr download_url=http%3A%2F%2Fcdimage.debian.org%2Fdebian-cd%2F6.0.6%2Famd64%2Fbt-cd%2Fdebian-6.0.6-amd64-CD-1.iso.torrent &download_dir=L0Rpc3F1ZSBkdXIvVMOpbMOpY2hhcmdlbWVudHMv ``` Example response: ```json { "result": { "id": 23 }, "success": true } ``` Example request : Multiple downloads at once: ```http POST /api/v{version}/downloads/add HTTP/1.1 Host: mafreebox.freebox.fr download_url_list=ftp%3A%2F%2Ftest-debit.free.fr%2F1024.rnd %0Ahttp%3A%2F%2Ftest-debit.free.fr%2F4096.rnd %0Ahttp%3A%2F%2Ftest-debit.free.fr%2F32768.rnd &download_dir=L0Rpc3F1ZSBkdXIvVMOpbMOpY2hhcmdlbWVudHMv ``` Example response: ```json { "result": { "id": [ 32, 33, 34 ] }, "success": true } ``` ###### Adding by file upload Supported files are .torrent, .nzb, Example request: ```http POST /api/v{version}/downloads/add HTTP/1.1 Host: mafreebox.freebox.fr Content-Type: multipart/form-data; boundary=---------------------------176791920111939857911845395343 Content-Length: 26651 -----------------------------176791920111939857911845395343 Content-Disposition: form-data; name="download_dir" L0Rpc3F1ZSBkdXIvVMOpbMOpY2hhcmdlbWVudHMv -----------------------------176791920111939857911845395343 Content-Disposition: form-data; name="archive_password" -----------------------------176791920111939857911845395343 Content-Disposition: form-data; name="download_file"; filename="debian-6.0.6-amd64-CD-1.iso.torrent" Content-Type: application/x-bittorrent d8:announce41:http://bttracker.debian.org:6969/announce7:comment [ ... ] ``` Example response: ```json { "result": { "id": 42 }, "success": true } ``` ### Download Stats If you just want to display synthetic information about downloader this is the method to use. #### Download Nzb configuration status Object ##### Object `NzbConfigStatus` | Property | Type | Access | Description | | --- | --- | --- | --- | | `status` | string | read-only | The valid config status are: Values: `not_checked` (config has not been checked yet), `checking` (test in progress), `error` (config is invalid, see error), `ok` (config is ok). | | `error` | string | read-only | The valid config status are: Values: `none` (test is ok), `nzb_authentication_required` (authentication is required), `bad_authentication` (incorrect credentials), `connection_refused` (unable to connect to NNTP server). | #### Download DHT stats Object ##### Object `DhtStats` | Property | Type | Access | Description | | --- | --- | --- | --- | | `enabled` | boolean | read-only | is the dht enabled | | `node_count` | integer | read-only | number of active nodes | | `enabled_ipv6` | boolean | read-only | is the dht enabled on IPv6 | | `node_count_ipv6` | integer | read-only | number of active nodes on IPv6 | #### Download Stats Object ##### Object `DownloadStats` | Property | Type | Access | Description | | --- | --- | --- | --- | | `nb_tasks` | integer | read-only | total number of tasks | | `nb_tasks_stopped` | integer | read-only | number of stopped tasks | | `nb_tasks_checking` | integer | read-only | number of checking tasks | | `nb_tasks_queued` | integer | read-only | number of queued tasks | | `nb_tasks_extracting` | integer | read-only | number of extracting tasks | | `nb_tasks_done` | integer | read-only | number of done tasks | | `nb_tasks_repairing` | integer | read-only | number of repairing tasks | | `nb_tasks_seeding` | integer | read-only | number of seeding tasks | | `nb_tasks_downloading` | integer | read-only | number of downloading tasks | | `nb_tasks_error` | integer | read-only | number of error tasks | | `nb_tasks_stopping` | integer | read-only | number of stopping tasks | | `nb_tasks_active` | integer | read-only | number of active tasks (checking + queued + extracting + repairing + seeding + downloading) | | `nb_rss` | integer | read-only | number of RSS feed subscriptions | | `nb_rss_items_unread` | integer | read-only | number of unread RSS items | | `rx_rate` | integer | read-only | current receive rate in bytes / second | | `tx_rate` | integer | read-only | current transmit rate in bytes / second | | `throttling_mode` | string | read-only | active throttling_mode (see DlThrottlingConfig) | | `throttling_is_scheduled` | boolean | read-only | if true, the current throttling mode has been computed using the throttling schedule if false, the current throttling mode has been manually forced | | `throttling_rate` | DlRate | read-only | current rate for throttling | | `nzb_config_status` | NzbConfigStatus | read-only | current nzb configuration status | | `conn_ready` | boolean | read-only | is the connection ready | | `nb_peer` | integer | read-only | number of bittorrent peers | | `blocklist_entries` | integer | read-only | number of rules in blocklist | | `blocklist_hits` | integer | read-only | number of hits in blocklist | | `dht_stats` | DhtStats | read-only | dht stats | ##### Get the Download Stats ###### `GET /downloads/stats` *permission `downloader` (inferred)* Response `result`: DownloadStats Example request: ```http GET /api/v{version}/downloads/stats HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```json { "success": true, "result": { "throttling_rate": { "rx_rate": 0, "tx_rate": 0 }, "nb_tasks_stopped": 1, "nb_tasks_checking": 0, "nb_tasks_queued": 0, "nb_tasks_extracting": 4, "nb_tasks_done": 1, "nb_tasks_repairing": 0, "throttling_mode": "normal", "nb_tasks_active": 11, "tx_rate": 4294, "nb_tasks_downloading": 4, "throttling_is_scheduled": true, "nb_tasks": 13, "nb_tasks_error": 0, "nb_tasks_stopping": 0, "nb_rss_items_unread": 5, "rx_rate": 14222, "nb_tasks_seeding": 3 } } ``` ### Download Files #### Download Files Object Each `Download` has one or more `DownloadFile`. ##### Object `DownloadFile` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | string | read-only | opaque id | | `task_id` | integer | read-only | id of the download task | | `path` | string | read-only | [ DEPRECATED ] | | `filepath` | string | read-only | full filepath on the disk (encoded as in file system api) | | `name` | string | read-only | file name | | `mimetype` | string | read-only | file mimetype | | `size` | integer | read-only | file size in bytes | | `rx` | integer | read-only | received bytes | | `status` | string | read-only | file download status Values: `queued` (file is queued for download), `error` (there was a problem with this file, see error to get the error code), `done` (file download is completed). | | `error` | string | read-only | file error code in case status is error | | `priority` | string | | file download priority inside the download task Documented values: `no_dl` (this file will not be downloaded), `low` (low priority), `normal` (default priority), `high` (high priority). | | `preview_url` | string | read-only | url to preview downloaded file (only available for bittorrent) as a share link, this url can be use without requiring any form of authentication so that it can be passed as-is to any software. | #### Download Files API ##### Get the list of files for a given Download ###### `GET /downloads/{task_id}/files` *permission `downloader` (inferred)* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `task_id` | path | integer | | Response `result`: DownloadFile[] Example request: ```http GET /api/v{version}/downloads/37/files HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```json { "success": true, "result": [ { "path": "/Disque dur/Téléchargements//test-debit.free.fr.html", "id": "5-1", "task_id": "5", "filepath": "L0Rpc3F1ZSBkdXIvVMOpbMOpY2hhcmdlbWVudHMvL3Rlc3QtZGViaXQuZnJlZS5mci5odG1s", "mimetype": "text/html", "name": "test-debit.free.fr.html", "rx": 0, "status": "done", "priority": "normal", "error": "none", "size": 0 }, { "path": "/Disque dur/Téléchargements//test-debit.free.fr/1024.rnd", "id": "5-7", "task_id": "5", "filepath": "L0Rpc3F1ZSBkdXIvVMOpbMOpY2hhcmdlbWVudHMvL3Rlc3QtZGViaXQuZnJlZS5mci8xMDI0LnJuZA==", "mimetype": "application/octet-stream", "name": "1024.rnd", "rx": 1048576, "status": "done", "priority": "low", "error": "none", "size": 1048576 }, { "path": "/Disque dur/Téléchargements//test-debit.free.fr/image.iso", "id": "5-16", "task_id": "5", "filepath": "L0Rpc3F1ZSBkdXIvVMOpbMOpY2hhcmdlbWVudHMvL3Rlc3QtZGViaXQuZnJlZS5mci9pbWFnZS5pc28=", "mimetype": "application/x-cd-image", "name": "image.iso", "rx": 678428672, "status": "done", "priority": "low", "error": "none", "size": 678428672 } ] } ``` ##### Change the priority of a Download File ###### `PUT /downloads/{task_id}/files/{file_id}` *permission `downloader` (inferred)* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `task_id` | path | integer | The download task id | | `file_id` | path | string | | Request body (`application/json`): { path: string, priority: string } Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http PUT /api/v{version}/downloads/37/files/37-4 HTTP/1.1 Host: mafreebox.freebox.fr { "priority": "high" } ``` Example response: ```json { "success": true } ``` ### Download Trackers [UNSTABLE] #### Download Tracker Object Each torrent `Download` task has one or more `DownloadTracker`. Each tracker is identified by its announce URL. ##### Object `DownloadTracker` | Property | Type | Access | Description | | --- | --- | --- | --- | | `announce` | string | read-only | tracker announce URL | | `is_backup` | boolean | read-only | true if the tracker is a backup tracker (the downloader won’t connect to this tracker unless the primary tracker fails) | | `status` | string | read-only | tracker status Values: `unannounced` (not announced), `announcing` (announcing), `announce_failed` (an error occurred while trying to announce), `announced` (announced). | | `interval` | integer | read-only | desired interval between two announces (in seconds) | | `min_interval` | integer | read-only | minimum interval between two announces (in seconds) | | `reannounce_in` | integer | read-only | time left before reannounce (in seconds) | | `nseeders` | integer | read-only | number of seeders announced on tracker | | `nleechers` | integer | read-only | number of leechers announced on tracker | | `is_enabled` | boolean | | is the tracker enabled | #### Download Tracker API ##### Get the list of trackers for a given Download Attempting to call this method on a download other than bittorent will fail ###### `GET /downloads/{task_id}/trackers` *permission `downloader` (inferred) · unstable* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `task_id` | path | integer | | Response `result`: DownloadTracker[] Example request: *The documentation example uses `GET /downloads/35/tracker`, which differs from the operation path.* ```http GET /api/v{version}/downloads/35/tracker HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```json { "success": true, "result": [ { "nseeders": 0, "nleechers": 0, "reannounce_in": 790, "is_backup": false, "interval": 900, "min_interval": 60, "announce": "http://bttracker.debian.org:6969/announce", "status": "announced" } ] } ``` ##### Add a new tracker Attempting to call this method on a download other than bittorent will fail ###### `POST /downloads/{task_id}/trackers` *permission `downloader` (inferred) · unstable* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `task_id` | path | integer | | Request body (`application/json`): { announce: string } Response: no result schema documented (envelope `{ "success": true }`). Example request: *The documentation example uses `POST /downloads/35/tracker`, which differs from the operation path.* ```http POST /api/v{version}/downloads/35/tracker HTTP/1.1 Host: mafreebox.freebox.fr { "announce": "udp://tracker.openbittorrent.com:80" } ``` Example response: ```json { "success": true } ``` ##### Remove a tracker ###### `DELETE /downloads/{task_id}/trackers/{announce}` *permission `downloader` (inferred) · unstable* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `task_id` | path | integer | | | `announce` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). Example request: *The documentation example uses `DELETE /downloads/35/tracker/udp%3A%2F%2Ftracker.openbittorrent.com%3A80`, which differs from the operation path.* ```http DELETE /api/v{version}/downloads/35/tracker/udp%3A%2F%2Ftracker.openbittorrent.com%3A80 HTTP/1.1 Host: mafreebox.freebox.fr { "announce": "udp://tracker.openbittorrent.com:80" } ``` Example response: ```json { "success": true } ``` ##### Update a tracker ###### `PUT /downloads/{task_id}/trackers/{announce}` *permission `downloader` (inferred) · unstable* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `task_id` | path | integer | | | `announce` | path | string | | Request body (`application/json`): { announce: string, is_enabled: boolean } Response: no result schema documented (envelope `{ "success": true }`). Example request: *The documentation example uses `PUT /downloads/35/tracker/udp%3A%2F%2Ftracker.openbittorrent.com%3A80`, which differs from the operation path.* ```http PUT /api/v{version}/downloads/35/tracker/udp%3A%2F%2Ftracker.openbittorrent.com%3A80 HTTP/1.1 Host: mafreebox.freebox.fr { "announce": "udp://tracker.openbittorrent.com:80", "is_enabled": true } ``` Example response: ```json { "success": true } ``` ### Download Peers [UNSTABLE] #### Download Peer Object Each torrent `Download` task has one or more `DownloadPeer`. ##### Object `DownloadPeer` | Property | Type | Access | Description | | --- | --- | --- | --- | | `host` | string | read-only | peer IP | | `port` | integer | read-only | peer port | | `state` | string | read-only | peer state Values: `disconnected` (not connected), `connecting` (trying to connect to the peer), `handshaking` (connected to the peer, negotiating capabilities), `ready` (ready to exchange data). | | `origin` | string | read-only | peer origin Values: `tracker` (got the peer from the tracker), `incoming` (incoming peer), `dht` (got the peer from DHT), `pex` (got the peer from Peer exchange protocol), `user` (manually added peer). | | `protocol` | string | read-only | Values: `tcp` (TCP), `tcp_obfuscated` (Obfuscated TCP), `udp` (UDP). | | `client` | string | read-only | Bittorrent client name | | `country_code` | string | read-only | Peer country code (iso 3166) If country code is not available it will have the value “??” | | `tx` | integer | read-only | transmitted bytes | | `rx` | integer | read-only | received bytes | | `tx_rate` | integer | read-only | current transmit rate in byte/s | | `rx_rate` | integer | read-only | current receive rate in byte/s | | `progress` | integer | read-only | peer current download progress | | `requests` | integer[] | read-only | current requested pieces | ##### Get the list of peers for a given Download Attempting to call this method on a download other than bittorent will fail ###### `GET /downloads/{task_id}/peers` *permission `downloader` (inferred) · unstable* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `task_id` | path | integer | | Response `result`: { protocol: string, origin: string, progress: integer, remote_choke: boolean, requests: object, host: string, port: integer, client: string, country_code: string, local_interest: boolean, state: string, rx: integer, tx: integer, remote_interest: boolean, tx_rate: integer, rx_rate: integer, local_choke: boolean }[] Example request: ```http GET /api/v{version}/downloads/42/peers HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```json { "success": true, "result": [ { "protocol": "tcp_obfuscated", "origin": "tracker", "progress": 91, "remote_choke": true, "requests": {}, "host": "186.213.200.201", "port": 0, "client": "Azureus 4.7.2.0", "country_code": "BR", "local_interest": false, "state": "ready", "rx": 1617, "tx": 836670, "remote_interest": true, "tx_rate": 0, "rx_rate": 0, "local_choke": false }, { "protocol": "tcp", "origin": "tracker", "progress": 11, "remote_choke": true, "requests": {}, "host": "208.127.4.60", "port": 0, "client": "Transmission 2.51", "country_code": "US", "local_interest": false, "state": "ready", "rx": 8929, "tx": 7592234, "remote_interest": true, "tx_rate": 0, "rx_rate": 0, "local_choke": false } ] } ``` ### Download Pieces Each Torrent is split in ‘pieces’ of fixed size. The Download Piece Api allow tracking the download state of each pieces of a Torrent #### Get the pieces status a given download The result value is a string, with each character representing a piece status. Piece status can be: | Status | Description | | --- | --- | | X | piece is complete | | | piece is currently downloading | | . | piece is wanted but not downloading yet | | | piece is not wanted and will not be downloaded | | / | piece is downloading with high priority as it is needed for file preview | | U | piece is scheduled with high priority as it is needed for file preview | ##### `GET /downloads/{task_id}/pieces` *permission `downloader` (inferred)* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `task_id` | path | integer | | Response `result`: string Example request: ```http GET /api/v{version}/downloads/5/pieces HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```json { "success": true, "result": "XXXXX//++....-- [ ... ] XXX" } ``` ### Download Blacklist [UNSTABLE] For bittorrent downloads, we use a blacklist to store information about “useless” or broken peers. For instance if a peer is complete and we are trying to seed data, there is no use attempting to connect to this peer again. The download blacklist api allow you to retrieve information about this blacklist, and remove, or add peers to the blacklist. Each `DownloadBlacklistEntry` can be specific to a torrent, or “global” and apply to any torrent. #### Download Blacklist Object ##### Object `DownloadBlacklistEntry` | Property | Type | Access | Description | | --- | --- | --- | --- | | `host` | string | read-only | entry ip | | `reason` | string | read-only | blacklist reason Values: `not_blacklisted`, `crypto_not_supported` (peer does not support encrypted connection), `connect_fail` (failed to connect), `hs_timeout` (handshake timeout), `hs_failed` (handshake failed), `hs_crypt_failed` (handshake failed during crypto), `hs_crypto_disabled` (handshake failed because encryption is disabled), `torrent_not_found` (torrent not found), `read_failed` (failed to read from peer), `write_failed` (failed to send data to peer), `crap_received` (received invalid data from peer), `conn_closed` (connection closed by remote peer), `timeout` (timeout), `blocklist` (peer is in a blocked ip range), `user` (manually blacklisted). | | `expire` | integer | read-only | time left before blacklist removal | | `global` | boolean | read-only | does this entry applies to all torrents | ##### Get the list of blacklist entries for a given download Attempting to call this method on a download other than bittorent will fail. ###### `GET /downloads/{task_id}/blacklist` *permission `downloader` (inferred) · unstable* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `task_id` | path | integer | | Response `result`: DownloadBlacklistEntry[] Example request: ```http GET /api/v{version}/downloads/5/blacklist HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```json { "success": true, "result": [ { "host": "89.215.188.6", "expire": 90, "global": true, "reason": "torrent_not_found" }, { "host": "94.23.0.89", "expire": 120, "global": true, "reason": "conn_closed" }, { "host": "188.254.151.215", "expire": 150, "global": true, "reason": "timeout" }, { "host": "201.25.54.26", "expire": 180, "global": true, "reason": "timeout" } ] } ``` ##### Empty the blacklist for a given download This call allow to remove all global entries, and entries related to the given download ###### `DELETE /downloads/{task_id}/blacklist/empty` *permission `downloader` (inferred) · unstable* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `task_id` | path | integer | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/downloads/5/blacklist/empty HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```json { "success": true } ``` ##### Delete a particular blacklist entry ###### `DELETE /downloads/blacklist/{host}` *permission `downloader` (inferred) · unstable* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `host` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/downloads/blacklist/201.25.54.26 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```json { "success": true } ``` ##### Add a blacklist entry ###### `POST /downloads/blacklist` *permission `downloader` (inferred) · unstable* Request body (`application/json`): { host: string, expire: integer } Response `result`: DownloadBlacklistEntry Example request: ```http POST /api/v{version}/downloads/blacklist HTTP/1.1 Host: mafreebox.freebox.fr { "host": "8.8.8.8", "expire": 3600 } ``` Example response: ```json { "success": true, "result": { "host": "197.200.139.87", "expire": 300, "global": true, "reason": "user" } } ``` ### Download Feeds The Freebox downloader supports subscribing to RSS feeds, for automatic content download. #### Download Feed object Download Feeds have the following attributes: ##### Object `DownloadFeed` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | read-only | id | | `status` | string | read-only | The feed can have the following status Values: `ready` (feed is up to date), `fetching` (feed is updating), `error` (there was an error trying to refresh this feed, see error). | | `url` | string | read-only | Feed URL | | `title` | string | read-only | Feed title (extracted from the RSS) | | `desc` | string | read-only | Feed description (extracted from the RSS) | | `image_url` | string | read-only | Feed image URL (extracted from the RSS) | | `nb_read` | integer | read-only | Number of read items in the feed | | `nb_unread` | integer | read-only | Number of unread items in the feed | | `auto_download` | boolean | | If set to true, the downloader will automatically download new items | | `fetch_ts` | integer (unix-time) | read-only | UNIX timestamp (seconds) Last time the feed was fetched | | `pub_ts` | integer (unix-time) | read-only | UNIX timestamp (seconds) Last time the feed was published on remote server | | `error` | string | read-only | Error code (same as used in Download or DownloadFile). | #### Download Feed Errors When attempting to access the download feed API, you may encounter the following errors: | error_code | Description | | --- | --- | | feed_not_found | No feed was found with the given id | | item_not_found | No feed item was found with the given id | | feed_is_recent | You are trying to update a feed that is already up to date | | internal_error | Internal error | #### Download Feed API ##### Get the list of all download Feeds ###### `GET /downloads/feeds/` *permission `downloader` (inferred)* Returns the collection of all DownloadFeed feeds Response `result`: DownloadFeed[] Example request: ```http GET /api/v{version}/downloads/feeds/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "auto_download": false, "id": 1, "desc": "Custom RSS feed based off search filters.", "error": "none", "nb_read": 0, "title": "ezRSS - Search Results", "image_url": "http://ezrss.it/images/ezrssit.png", "status": "ready", "url": "http://www.ezrss.it/search/index.php?show_name=Ubuntu&mode=rss", "nb_unread": 29, "fetch_ts": 1349885023, "pub_ts": 1350583600 }, { "auto_download": false, "id": 2, "desc": "Latest nzb for Debian", "error": "none", "nb_read": 0, "title": "Debian NZB RSS", "image_url": "", "status": "ready", "url": "http://www.nzb-rss.com/rss/Debian.rss", "nb_unread": 13, "fetch_ts": 1350469391, "pub_ts": 1350583600 } ] } ``` ##### Get a download Feed ###### `GET /downloads/feeds/{id}` *permission `downloader` (inferred)* Gets the DownloadFeed with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: DownloadFeed Example request: ```http GET /api/v{version}/downloads/feeds/2 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "auto_download": false, "id": 2, "desc": "Latest nzb for Debian", "error": "none", "nb_read": 0, "title": "Debian NZB RSS", "image_url": "", "status": "ready", "url": "http://www.nzb-rss.com/rss/Debian.rss", "nb_unread": 13, "fetch_ts": 1350469391, "pub_ts": 1350583600 } } ``` ##### Add a Download Feed ###### `POST /downloads/feeds/` *permission `downloader` (inferred)* Creates a new DownloadFeed. Request body (`application/json`): DownloadFeed Response `result`: DownloadFeed Example request: ```http POST /api/v{version}/downloads/feeds/ HTTP/1.1 Host: mafreebox.freebox.fr { "url": "http://www.nzb-rss.com/rss/Debian-unstable.rss" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "auto_download": false, "error": "none", "desc": "", "status": "ready", "nb_read": 0, "title": "", "image_url": "", "feed_id": 6, "url": "http://www.nzb-rss.com/rss/Debian-unstable.rss", "nb_unread": 0, "fetch_ts": 0, "pub_ts": 1350583600 } } ``` ##### Delete Download Feed ###### `DELETE /downloads/feeds/{id}` *permission `downloader` (inferred)* Deletes the DownloadFeed and all the associated items. This will not alter the Download tasks. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/downloads/feeds/1 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Update a Download Feed ###### `PUT /downloads/feeds/{id}` *permission `downloader` (inferred)* Updates the DownloadFeed task with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Request body (`application/json`): DownloadFeed Response `result`: DownloadFeed Example request: ```http PUT /api/v{version}/downloads/feeds/2 HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "auto_download": true } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "auto_download": true, "error": "none", "desc": "Latest nzb for Debian", "title": "Debian NZB RSS", "status": "ready", "nb_read": 0, "image_url": "", "feed_id": 2, "url": "http://www.nzb-rss.com/rss/Debian.rss", "nb_unread": 13, "fetch_ts": 1350583674, "pub_ts": 1350583600 } } ``` ##### Refresh a Download Feed ###### `POST /downloads/feeds/{id}/fetch` *permission `downloader` (inferred)* Remotely fetches the RSS feed and updates it. Note that if the remote feed specifies a TTL, trying to update before the ttl will result in feed_is_recent error | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http POST /api/v{version}/downloads/feeds/2/fetch HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Refresh all Download Feeds ###### `POST /downloads/feeds/fetch` *permission `downloader` (inferred)* Remotely fetches all the RSS feeds. Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http POST /api/v{version}/downloads/feeds/fetch HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` #### Download Feed Item object Each RSS `DownloadFeed` contains feed items object ##### Object `DownloadFeedItem` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | read-only | id | | `feed_id` | integer | read-only | id of the DownloadFeed | | `title` | string | read-only | item title | | `desc` | string | read-only | item description | | `author` | string | read-only | item author | | `link` | string | read-only | URL of the RSS feed attachment | | `is_read` | boolean | | you can mark the item as read manually, or it is marked as read automatically when the item is downloaded | | `is_downloaded` | boolean | read-only | mark downloaded items, automatically set to true when RSS item is downloaded | | `fetch_ts` | integer (unix-time) | read-only | UNIX timestamp (seconds) timestamp of the item creation | | `pub_ts` | integer (unix-time) | read-only | UNIX timestamp (seconds) item publish timestamp | | `enclosure_url` | string | read-only | enclosure URL (if specified in RSS feed) | | `enclosure_type` | string | read-only | enclosure mime type (if specified in RSS feed) | | `enclosure_length` | integer | read-only | enclosure size in bytes (if specified in RSS feed) | ##### Get the items of a given RSS feed ###### `GET /downloads/feeds/{feed_id}/items/` *permission `downloader` (inferred)* Returns the collection of all DownloadFeedItems for a given DownloadFeed | Parameter | In | Type | Description | | --- | --- | --- | --- | | `feed_id` | path | integer | | Response `result`: DownloadFeed[] Example request: ```http GET /api/v{version}/downloads/feeds/2/items/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "pub_ts": 1350657300, "fetch_ts": 1350657317, "is_read": true, "title": "debian-6.0.4-amd64-CD-1.iso", "link": "http://bttracker.debian.org:6969/file/debian-6.0.4-amd64-CD-1.iso.torrent?info_hash=95ce23e889cc26901740f87ac25270da725bfd36", "id": 2845, "author": "debian", "feed_id": 2, "desc": "" }, { "pub_ts": 1350657300, "fetch_ts": 1350657318, "is_read": false, "title": "debian-6.0.4-amd64-CD-2.iso", "link": "http://bttracker.debian.org:6969/file/debian-6.0.4-amd64-CD-2.iso.torrent?info_hash=34583a8e25ef1528a8bfce99d24f401acb24d982", "id": 2846, "author": "debian", "feed_id": 2, "desc": "" } ] } ``` ##### Update a feed item ###### `PUT /downloads/feeds/{feed_id}/items/{item_id}` *permission `downloader` (inferred)* Returns the collection of all DownloadFeedItems for a given DownloadFeed | Parameter | In | Type | Description | | --- | --- | --- | --- | | `feed_id` | path | integer | | | `item_id` | path | integer | | Request body (`application/json`): { is_read: boolean } Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http PUT /api/v{version}/downloads/feeds/2/items/2846 HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "is_read": true } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Download a feed item ###### `POST /downloads/feeds/{feed_id}/items/{item_id}/download` *permission `downloader` (inferred)* This method will enqueue the RSS item to the download list | Parameter | In | Type | Description | | --- | --- | --- | --- | | `feed_id` | path | string | | | `item_id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). ##### Mark all items as read ###### `POST /downloads/feeds/{feed_id}/items/mark_all_as_read` *permission `downloader` (inferred)* This method will mark each items as read | Parameter | In | Type | Description | | --- | --- | --- | --- | | `feed_id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). ### Download Configuration #### Download configuration object The download configuration is a singleton used to store the downloader preferences. ##### Global config ###### Object `DownloadConfiguration` | Property | Type | Access | Description | | --- | --- | --- | --- | | `max_downloading_tasks` | integer | | max concurrent download tasks | | `download_dir` | string | | the default path where downloads will be stored (base64 encoded) | | `watch_dir` | string | | special folder that will be monitored. When a new supported file (.nzb, .torrent) is copied in that folder, the task is automatically added to the download queue. (base64 encoded) | | `use_watch_dir` | boolean | | if set to false, the watch_dir will not be monitored | | `throttling` | DlThrottlingConfig | | throttling configuration | | `news` | DlNewsConfig | | newsgroups configuration | | `bt` | DlBtConfig | | bittorrent configuration | | `feed` | DlFeedConfig | | RSS feed configuration | | `blocklist` | DlBlockListConfig | | block list configuration | | `dns1` | string | | dns server ip to use for downloader (leave blank for default dns server) | | `dns2` | string | | dns server ip to use for downloader | ##### Throttling config ###### Object `DlThrottlingConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `normal` | DlRate | | download rate for normal time slot (in B/s) | | `slow` | DlRate | | download rate for normal slow slot (in B/s) | | `schedule` | string[] (max 168) | | The schedule array represent the list of week hours timeslot, starting on monday a midnight. Therefore the complete week is represented in a array of 168 elements (24 * 7) Each slot can have the following value: Item values: `normal` (downloads will use normal DlRate config for this timeslot), `slow` (downloads will use slow DlRate config for this timeslot), `hibernate` (downloads will be paused for this timeslot). | | `mode` | string | | Throttling mode can have to following values Values: `normal` (force use of normal rate limits (not using the scheduler)), `slow` (force use of slow rate limits (not using the scheduler)), `hibernate` (force hibernate (not using the scheduler)), `schedule` (use scheduded rate limit). | ###### Object `DlRate` | Property | Type | Access | Description | | --- | --- | --- | --- | | `tx_rate` | integer | | maximum transmit rate (in byte/s) 0 means no limit | | `rx_rate` | integer | | maximum receive rate (in byte/s) 0 means no limit | ##### Newsgroups config ###### Object `DlNewsConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `server` | string | | NNTP server hostname | | `port` | integer | | NNTP server port | | `ssl` | boolean | | Use SSL to connect to server if set to true | | `user` | string | | NNTP auth username (can be empty if no auth is required) | | `password` | string | write-only | NNTP auth password (can be empty if no auth is required) | | `nthreads` | integer | | maximum concurrent connections to the NNTP server | | `auto_repair` | boolean | | automatically check and repair downloaded files using the provided par2 files | | `lazy_par2` | boolean | | if set to true the downloader will download the par2 files only if the download is corrupted | | `auto_extract` | boolean | | automatically attempt to extract downloaded files | | `erase_tmp` | boolean | | if auto_extract is enabled, delete archive files once successfully extracted | ##### Bittorrent config ###### Object `DlBtConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `max_peers` | integer | | maximum number of peers at a given time | | `stop_ratio` | integer | | default stop_ratio for bt Download tasks This value is scaled by a factor 100, for instance a stop_ratio of 200 means that the task will stop once tx_bytes = 2 * size A value of 0 means that the task will continue seeding until it is manually stopped | | `crypto_support` | string | | The crypto_support can have the following values Values: `unsupported` (will never use bittorrent crypto), `allowed` (will select plain during handshake), `preferred` (will select crypto during handshake), `required` (will allow plain bittorrent). | | `enable_dht` | boolean | | enable the dht protocol | | `enable_pex` | boolean | | enable the peer exchange protocol | | `announce_timeout` | integer | | timeout in seconds for announcing to tracker | | `main_port` | integer | | main bittorrent port | | `dht_port` | integer | | bittorrent dht port | ##### Rss Feeds config ###### Object `DlFeedConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `fetch_interval` | integer | | interval between automatic RSS refresh (in minutes) | | `max_items` | integer | | maximum feed item to keep | ##### BlockList config ###### Object `DlBlockListConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `sources[]` | string | | list of block list URL source The block list should be in cidr format e.g.: http://list.iblocklist.com/?list=bt_level1&fileformat=cidr&archiveformat= | #### Get the current Download configuration ##### `GET /downloads/config/` *permission `downloader` (inferred)* Returns the current DownloadConfiguration Response `result`: DownloadConfiguration Example request: ```http GET /api/v{version}/downloads/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "feed": { "max_items": 0, "fetch_interval": 60 }, "use_watch_dir": true, "watch_dir": "L0Rpc3F1ZSBkdXIvLnF1ZXVl", "news": { "user": "", "erase_tmp": true, "port": 119, "nthreads": 1, "auto_repair": true, "ssl": false, "auto_extract": true, "lazy_par2": true, "server": "news.free.fr" }, "bt": { "max_peers": 50, "stop_ratio": 150, "crypto_support": "allowed" }, "max_downloading_tasks": 5, "download_dir": "L0Rpc3F1ZSBkdXIvVMOpbMOpY2hhcmdlbWVudHMv", "throttling": { "normal": { "rx_rate": 0, "tx_rate": 0 }, "slow": { "rx_rate": 512, "tx_rate": 42 }, "schedule": [ "slow", "normal", "normal", "normal", "normal", "normal", "slow" ], "mode": "normal" } } } ``` #### Update the Download configuration ##### `PUT /downloads/config/` *permission `downloader` (inferred)* Updates the DownloadConfiguration Request body (`application/json`): DownloadConfiguration Response `result`: DownloadConfiguration Example request: ```http PUT /api/v{version}/downloads/config/ HTTP/1.1 Host: mafreebox.freebox.fr { "throttling": { "normal": { "rx_rate": 512, "tx_rate": 40 }, "slow": { "rx_rate": 128, "tx_rate": 10 }, "mode": "normal", "schedule": [ "slow", "normal", "normal", "normal", "normal", "normal", "normal", "slow" ] }, "max_downloading_tasks": 5, "download_dir": "L0Rpc3F1ZSBkdXIvVMOpbMOpY2hhcmdlbWVudHMv", "use_watch_dir": true, "watch_dir": "L0Rpc3F1ZSBkdXIvLnF1ZXVl", "news": { "server": "news.free.fr", "port": "119", "ssl": false, "nthreads": 1, "user": "", "lazy_par2": true, "auto_repair": true, "auto_extract": true, "erase_tmp": true }, "bt": { "max_peers": 50, "stop_ratio": 150, "crypto_support": "allowed" }, "feed": { "fetch_interval": 60 } } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "feed": { "max_items": 0, "fetch_interval": 60 }, "use_watch_dir": true, "watch_dir": "L0Rpc3F1ZSBkdXIvLnF1ZXVl", "news": { "user": "", "erase_tmp": true, "port": 119, "nthreads": 1, "auto_repair": true, "ssl": false, "auto_extract": true, "lazy_par2": true, "server": "news.free.fr" }, "bt": { "max_peers": 50, "stop_ratio": 150, "crypto_support": "allowed" }, "max_downloading_tasks": 5, "download_dir": "L0Rpc3F1ZSBkdXIvVMOpbMOpY2hhcmdlbWVudHMv", "throttling": { "normal": { "rx_rate": 512, "tx_rate": 40 }, "slow": { "rx_rate": 128, "tx_rate": 10 }, "schedule": [ "slow", "normal", "normal", "normal", "normal", "normal", "normal", "slow" ], "mode": "normal" } } } ``` ##### Updating the current Throttling mode ###### `PUT /downloads/throttling` *permission `downloader` (inferred)* You can force the throttling mode using this method. You can use any of the throttling modes defined in DlThrottlingConfig. Setting to schedule will automatically set correct throttling mode. Other values will force the throttling mode until you set it back to schedule. Request body (`application/json`): { throttling: string } Response `result`: { is_scheduled: boolean, throttling: string } Example request: ```http PUT /api/v{version}/downloads/throttling HTTP/1.1 Host: mafreebox.freebox.fr { "throttling": "slow" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "is_scheduled": false, "throttling": "slow" } } ``` ## File System Api ### File System With the file system API you can access files on Freebox internal disk and disks connected to the Freebox. #### Path encoding `NOTE:` For maximum compatibility issues path are encoded in base64, you *should* use the path as it is returned by the ls API call. For instance this will solve problems with [unicode equivalence](http://en.wikipedia.org/wiki/Unicode_equivalence) . Although “Spécial” (0x53 0x70 **0xc3 0xa9** 0x63 0x69 0x61 0x6c) and “Spécial” (0x53 0x70 **0x65 0xcc 0x81** 0x63 0x69 0x61 0x6c) are utf8 equivalent, it represents two different paths. Some software/libraries will replace the original string with its normalized form, causing issues. The use of base64 encoded path will ensure the original path will be preserved. #### File System Errors When attempting to access the file system API, you may encounter the following errors: | error_code | Description | | --- | --- | | invalid_id | Invalid object id | | path_not_found | File or folder not found | | internal_error | Internal error | | disk_unavailable | The disk is not mounted | | invalid_request | Invalid request | | invalid_conflict_mode | The conflict mode specified is invalid (see below) | | exec_failed | Internal error | | out_of_memory | Out of memory | | task_not_found | Invalid task id | | invalid_state | You tried to set an invalid state | | invalid_task_type | This operation cannot be performed on this task | | destination_conflict | The destination file/folder already exists | | access_denied | Access to this file is denied | | disk_full | The destination disk is full | #### Task File system tasks have the following attributes: ##### Object `FsTask` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | read-only | id | | `type` | string | read-only | The valid task types are: Values: `cat` (Concatenate multiple files), `cp` (Copy files), `mv` (Move files), `rm` (Remove files), `archive` (Creates an archive), `extract` (Extract an archive), `repair` (Check and repair files). | | `state` | string | | Values: `queued` (Queued (only one task is active at a given time)), `running` (Running), `paused` (Paused (user suspended)), `done` (Done), `failed` (Failed (see error)). | | `error` | string | read-only | Values: `none` (No error), `archive_read_failed` (Error reading archive), `archive_open_failed` (Error opening archive), `archive_write_failed` (Error writing archive), `chdir_failed` (Error changing directory), `dest_is_not_dir` (The destination is not a directory), `file_exists` (File already exists), `file_not_found` (File not found), `mkdir_failed` (Unable to create directory), `open_input_failed` (Error opening input file), `open_output_failed` (Error opening output file), `opendir_failed` (Error opening directory), `overwrite_failed` (Error overwriting file), `path_too_big` (Path is too long), `repair_failed` (Failed to repair corrupted files), `rmdir_failed` (Error removing directory), `same_file` (Source and Destination are the same file), `unlink_failed` (Error removing file), `unsupported_file_type` (This file type is not supported), `write_failed` (Error writing file), `disk_full` (Disk is full), `internal` (Internal error), `invalid_format` (Invalid file format (corrupted ?)), `incorrect_password` (Invalid or missing password for extraction), `permission_denied` (Permission denied), `readlink_failed` (Failed to read the target of a symbolic link), `symlink_failed` (Failed to create a symbolic link), `copy_into_itself` (Attempted to copy a directory to a subdirectory of itself), `truncate_failed` (Failed to truncate file). | | `created_ts` | integer (unix-time) | read-only | UNIX timestamp (seconds) task creation timestamp | | `started_ts` | integer (unix-time) | read-only | UNIX timestamp (seconds) task start timestamp | | `done_ts` | integer (unix-time) | read-only | UNIX timestamp (seconds) task end timestamp | | `duration` | integer | read-only | task duration in seconds | | `progress` | integer | read-only | task progress in percent (scaled by 100) | | `eta` | integer | read-only | estimated time remaining before the task completion (in seconds) | | `from` | string | read-only | current source file (if available) | | `to` | string | read-only | current destination file (if available) | | `nfiles` | integer | read-only | number of files to process | | `nfiles_done` | integer | read-only | number of files processed | | `total_bytes` | integer | read-only | total bytes to process | | `total_bytes_done` | integer | read-only | number of bytes processed | | `curr_bytes` | integer | read-only | size of the file currently processed | | `curr_bytes_done` | integer | read-only | number of bytes processed for the current file | | `rate` | integer | read-only | processing rate in byte/s | | `src` | string[] | read-only | task source files | | `dst` | string | read-only | task destination path | ##### List every tasks ###### `GET /fs/tasks/` *permission `explorer` (inferred)* Returns the collection of all FsTask tasks Response `result`: FsTask[] Example request: ```http GET /api/v{version}/fs/tasks/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "curr_bytes_done": 0, "total_bytes": 0, "nfiles_done": 0, "started_ts": 1355834253, "duration": 3, "done_ts": 0, "curr_bytes": 0, "type": "extract", "to": "oxygennosvg/128x128/mimetypes/application_x_nzb.png", "id": 12, "nfiles": 0, "created_ts": 1355834253, "state": "paused", "total_bytes_done": 0, "from": "/Disque dur/tests/oxygennosvg.tar.gz", "rate": 0, "eta": 0, "error": "none", "progress": 0, "src": [ "/Disque dur/tests/oxygennosvg.tar.gz" ], "dst": "/Disque dur/tests/oxygennosvg" }, { "id": 11, "curr_bytes_done": 0, "total_bytes": 0, "nfiles_done": 0, "started_ts": 1355834187, "duration": 0, "done_ts": 1355834187, "curr_bytes": 0, "type": "rm", "to": "", "nfiles": 0, "created_ts": 1355834187, "state": "done", "total_bytes_done": 0, "from": "/Disque dur/test/testiso.1.iso", "rate": 0, "eta": 0, "error": "none", "progress": 100, "src": [ "/Disque dur/test/testiso.1.iso" ] } ] } ``` ##### List a task ###### `GET /fs/tasks/{id}` *permission `explorer` (inferred)* Returns the FsTask task with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: FsTask Example request: ```http GET /api/v{version}/fs/tasks/12 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "curr_bytes_done": 0, "total_bytes": 0, "nfiles_done": 0, "started_ts": 1355834253, "duration": 268, "done_ts": 0, "curr_bytes": 0, "type": "extract", "to": "oxygennosvg/16x16/actions/format_stroke_color.png", "id": 12, "nfiles": 0, "created_ts": 1355834253, "state": "running", "total_bytes_done": 0, "from": "/Disque dur/tests/oxygennosvg.tar.gz", "rate": 0, "eta": 0, "error": "none", "progress": 0, "src": [ "/Disque dur/tests/oxygennosvg.tar.gz" ], "dst": "/Disque dur/tests/oxygennosvg" } } ``` ##### Delete a task ###### `DELETE /fs/tasks/{id}` *permission `explorer` (inferred)* Deletes the FsTask task with the given id, if the task was running, stop it. No rollback is done, if a file as already been processed it will be left as is. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/fs/tasks/12 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Update a task ###### `PUT /fs/tasks/{id}` *permission `explorer` (inferred)* Updates the FsTask task with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Request body (`application/json`): FsTask Response `result`: FsTask Example request: ```http PUT /api/v{version}/fs/tasks/15 HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "state": "paused" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "curr_bytes_done": 0, "total_bytes": 2410125312, "nfiles_done": 0, "started_ts": 1355835094, "duration": 27, "done_ts": 0, "curr_bytes": 0, "type": "cp", "to": "/Disque dur/old_hdd/testiso.1.iso", "id": 15, "nfiles": 1, "created_ts": 1355835094, "state": "paused", "total_bytes_done": 595591168, "from": "/Disque dur/old_hdd/testiso.iso", "rate": 0, "eta": 85, "error": "none", "progress": 24, "src": [ "/Disque dur/old_hdd/testiso.iso" ], "dst": "/Disque dur/old_hdd" } } ``` #### Listing ##### File info ###### Object `FileInfo` | Property | Type | Access | Description | | --- | --- | --- | --- | | `path` | string | read-only | file path (encoded in base64 as explained in Path Encoding) | | `name` | string | read-only | file name (in clear text) | | `mimetype` | string | read-only | file mimetype | | `type` | string | | Values: `dir` (Directory), `file` (Regular file). | | `size` | integer | read-only | file size in bytes | | `modification` | integer | read-only | file modification timestamp | | `index` | integer | read-only | display order for natural sort | | `link` | boolean | read-only | is this file a link | | `target` | string | read-only | symlink target path (encoded in base64 as explained in Path Encoding) (only present when link is set to true) | | `hidden` | boolean | read-only | should the file be hidden to user | | `foldercount` | integer | read-only | number of subfolders only relevant for dir, only provided if “countSubFolder” parameter is set | | `filecount` | integer | read-only | number of files inside directory only relevant for dir, only provided if “countSubFolder” parameter is set | | `exif` | object | read-only | EXIF metadada if available. only relevant for supported image files (JPEG, HEIC), when the “exifMode” parameter is set | ##### List files ###### `GET /fs/ls/{path}` *permission `explorer` (inferred)* Returns the list of FileInfos for the given path | Parameter | In | Type | Description | | --- | --- | --- | --- | | `path` | path | string | | | `onlyFolder` (optional) | query | boolean | Only list folders | | `countSubFolder` (optional) | query | boolean | Return files and subfolder count for folders | | `removeHidden` (optional) | query | boolean | Don’t return hidden files in directory listing | | `exifMode` (optional) | query | string | Return EXIF metadata for supported image files (JPEG, HEIC). Value can be “light” (basic metadata), “full” (all metadata) or “base64” (all metadata encoded in base64) | | `limit` (optional) | query | integer | Maximum number of entries in response [optional] | | `cursor` (optional) | query | string | Opaque value to include in next request to continue path listing [optional] | Response `result`: { entries: { path: string, filecount: integer, link: boolean, modification: integer, foldercount: integer, name: string, index: integer, mimetype: string, hidden: boolean, type: string, size: integer }[], cursor: string } Example request: ```http GET /api/v{version}/fs/ls/L0Rpc3F1ZSBkdXI=&limit=100 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "entries": [ { "path": "L0Rpc3F1ZSBkdXIvRW5yZWdpc3RyZW1lbnRz", "filecount": 0, "link": false, "modification": 1362005535, "foldercount": 0, "name": "Enregistrements", "index": 1, "mimetype": "inode/directory", "hidden": false, "type": "dir", "size": 4096 }, { "path": "L0Rpc3F1ZSBkdXIvTGUgU3DDqWNpYWwgMg==", "filecount": 0, "link": false, "modification": 1362492511, "foldercount": 0, "name": "Le Spécial 2", "index": 3, "mimetype": "inode/directory", "hidden": false, "type": "dir", "size": 4096 }, { "path": "L0Rpc3F1ZSBkdXIvTGUgU3BlzIFjaWFsIDI=", "filecount": 4, "link": false, "modification": 1361995307, "foldercount": 1, "name": "Le Spécial 2", "index": 4, "mimetype": "inode/directory", "hidden": false, "type": "dir", "size": 4096 }, { "path": "L0Rpc3F1ZSBkdXIvVmlkw6lvcw==", "filecount": 8, "link": false, "modification": 1361887598, "foldercount": 2, "name": "Vidéos", "index": 16, "mimetype": "inode/directory", "hidden": false, "type": "dir", "size": 4096 } ], "cursor": "eyJvZmZzZXQiOjIwMTMwMzk5MTQ2NzU5MzM4OTR9" } } ``` ##### Get file information ###### `GET /fs/info/{path}` *permission `explorer` (inferred)* Returns the FileInfos for the given path | Parameter | In | Type | Description | | --- | --- | --- | --- | | `path` | path | string | | Response `result`: FileInfo Example request: ```http GET /api/v{version}/fs/info/L0Rpc3F1ZSBkdXIvdG90bw== HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "type": "dir", "link": true, "parent": "L0Rpc3F1ZSBkdXI=", "modification": 1370354349, "hidden": false, "mimetype": "inode/directory", "name": "toto", "target": "L0Rpc3F1ZSBkdXIvUGhvdG9z", "path": "L0Rpc3F1ZSBkdXIvdG90bw==", "size": 4096 } } ``` ##### Batch file information ###### `POST /fs/info` *permission `explorer` (inferred)* Returns a FileInfos list for a given path list. Invalid paths are ignored. Request body (`application/json`): string[] Response `result`: FileInfo[] Example request: ```http POST /api/v{version}/fs/info HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json [ "L0Rpc3F1ZSBkdXIvRW5yZWdpc3RyZW1lbnRz", "L0Rpc3F1ZSBkdXIvTGUgU3DDqWNpYWwgMg==", "L0Rpc3F1ZSBkdXIvVmlkw6lvcw==" ] ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "path": "L0Rpc3F1ZSBkdXIvRW5yZWdpc3RyZW1lbnRz", "filecount": 0, "link": false, "modification": 1362005535, "foldercount": 0, "name": "Enregistrements", "index": 1, "mimetype": "inode/directory", "hidden": false, "type": "dir", "size": 4096 }, { "path": "L0Rpc3F1ZSBkdXIvTGUgU3DDqWNpYWwgMg==", "filecount": 0, "link": false, "modification": 1362492511, "foldercount": 0, "name": "Le Spécial 2", "index": 3, "mimetype": "inode/directory", "hidden": false, "type": "dir", "size": 4096 }, { "path": "L0Rpc3F1ZSBkdXIvVmlkw6lvcw==", "filecount": 8, "link": false, "modification": 1361887598, "foldercount": 2, "name": "Vidéos", "index": 16, "mimetype": "inode/directory", "hidden": false, "type": "dir", "size": 4096 } ] } ``` #### Operations Each time you want to perform a modification on the file system you will have to create a new `FsTask` that you will be able to monitor. NOTE: The requested operation may be en-queued to avoid performance drop because of excessive disk io ##### Conflict resolution For certain file operations where a file name conflict can happen, you must specify a conflict resolution mode. Valid resolution modes are: | Conflict mode | Description | | --- | --- | | overwrite | Overwrite the destination file | | both | Keep both files (rename the file adding a suffix) | | recent | Only overwrite if newer than destination file | | skip | Keep the destination file | ##### Move files ###### `POST /fs/mv/` *permission `explorer` (inferred)* Request body (`application/json`): { files: string[], dst: string, mode: string } Response `result`: FsTask Example request for moving files: ```http POST /api/v{version}/fs/mv/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "files": [ "L0Rpc3F1ZSBkdXIvUGhvdG9zL0RTQ18zNDkxLmpwZw==", "L0Rpc3F1ZSBkdXIvUGhvdG9zL0RTQ18zNTAwLmpwZw==" ], "dst": "L0Rpc3F1ZSBkdXIvUGhvdG9zL0xhdW5jaHBhZA==", "mode": "overwrite" } ``` Example response: ```json { "success": true, "result": { "curr_bytes_done": 0, "total_bytes": 0, "nfiles_done": 0, "started_ts": 1355840585, "duration": 0, "done_ts": 0, "curr_bytes": 0, "type": "mv", "to": "", "id": 39, "nfiles": 0, "created_ts": 1355840585, "state": "running", "total_bytes_done": 0, "from": "", "rate": 0, "eta": 0, "error": "none", "progress": 0, "src": [ "/Disque dur/Photos/DSC_3491.jpg", "/Disque dur/Photos/DSC_3500.jpg" ], "dst": "/Disque dur/Photos/Launchpad" } } ``` ##### Copy files ###### `POST /fs/cp/` *permission `explorer` (inferred)* Request body (`application/json`): { files: string[], dst: string, mode: string } Response `result`: FsTask Example request: ```http POST /api/v{version}/fs/cp/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "files": [ "L0Rpc3F1ZSBkdXIvUGhvdG9zL0xhdW5jaHBhZC9EU0NfMzQ5MS5qcGcK", "L0Rpc3F1ZSBkdXIvUGhvdG9zL0xhdW5jaHBhZC9EU0NfMzUwMC5qcGcK" ], "dst": "L0Rpc3F1ZSBkdXIvUGhvdG9zL1JvY2tldHMK", "mode": "both" } ``` Example response: ```json { "success": true, "result": { "curr_bytes_done": 0, "total_bytes": 0, "nfiles_done": 0, "started_ts": 1355840943, "duration": 0, "done_ts": 0, "curr_bytes": 0, "type": "cp", "to": "", "id": 43, "nfiles": 0, "created_ts": 1355840943, "state": "running", "total_bytes_done": 0, "from": "", "rate": 0, "eta": 0, "error": "none", "progress": 0, "src": [ "/Disque dur/Photos/Launchpad/DSC_3491.jpg", "/Disque dur/Photos/Launchpad/DSC_3500.jpg" ], "dst": "/Disque dur/Photos/Rockets" } } ``` ##### Remove files ###### `POST /fs/rm/` *permission `explorer` (inferred)* Request body (`application/json`): { files: string[] } Response `result`: FsTask Example request: ```http POST /api/v{version}/fs/rm/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "files": [ "L0Rpc3F1ZSBkdXIvUGhvdG9zL1JvY2tldHMvRFNDXzM0OTEuanBnCg==", "L0Rpc3F1ZSBkdXIvUGhvdG9zL1JvY2tldHMvRFNDXzM1MDAuanBnCg==" ] } ``` Example response: ```json { "success": true, "result": { "curr_bytes_done": 0, "total_bytes": 0, "nfiles_done": 0, "started_ts": 1355841064, "duration": 0, "done_ts": 0, "curr_bytes": 0, "type": "rm", "to": "", "id": 45, "nfiles": 0, "created_ts": 1355841064, "state": "running", "total_bytes_done": 0, "from": "/Disque dur/Photos/Rockets/DSC_3491.jpg", "rate": 0, "eta": 0, "error": "none", "progress": 0, "src": [ "/Disque dur/Photos/Rockets/DSC_3491.jpg", "/Disque dur/Photos/Rockets/DSC_3500.jpg" ] } } ``` ##### Cat files ###### `POST /fs/cat/` *permission `explorer` (inferred)* Or if you want to do a multi-volumes concatenation: Request body (`application/json`): { files: string[], dst: string, multi_volumes: boolean, delete_files: boolean, overwrite: boolean, append: boolean } Response `result`: FsTask Example request: ```http POST /api/v{version}/fs/cat/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "files": [ "L0Rpc3F1ZSBkdXIvZmlsZTE=", "L0Rpc3F1ZSBkdXIvZmlsZTI=" ], "dst": "L0Rpc3F1ZSBkdXIvZmlsZTEy", "multi_volumes": false, "delete_files": false, "append": true, "overwrite": false } ``` ```json { "files": [ "L0Rpc3F1ZSBkdXIvZmlsZTAwMQ==" ], "dst": "L0Rpc3F1ZSBkdXIvZmlsZQ==", "multi_volumes": true, "delete_files": true, "append": false, "overwrite": true } ``` Example response: ```json { "success": true, "result": { "curr_bytes_done": 0, "total_bytes": 0, "nfiles_done": 0, "started_ts": 1355840943, "duration": 0, "done_ts": 0, "curr_bytes": 0, "type": "cat", "to": "", "id": 43, "nfiles": 0, "created_ts": 1355840943, "state": "running", "total_bytes_done": 0, "from": "", "rate": 0, "eta": 0, "error": "none", "progress": 0 } } ``` ##### Create an archive ###### `POST /fs/archive/` *permission `explorer` (inferred)* Request body (`application/json`): { files: string[], dst: string } Response `result`: FsTask Example request: ```http POST /api/v{version}/fs/archive/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "files": [ "L0Rpc3F1ZSBkdXIvUGhvdG9zL0xhdW5jaHBhZC9EU0NfMzQ5MS5qcGc=", "L0Rpc3F1ZSBkdXIvUGhvdG9zL0xhdW5jaHBhZC9EU0NfMzUwMC5qcGc=" ], "dst": "L0Rpc3F1ZSBkdXIvUGhvdG9zL3JvY2tldHMuemlw" } ``` Example response: ```json { "success": true, "result": { "curr_bytes_done": 0, "total_bytes": 0, "nfiles_done": 0, "started_ts": 1355840943, "duration": 0, "done_ts": 0, "curr_bytes": 0, "type": "archive", "to": "", "id": 42, "nfiles": 0, "created_ts": 1355840943, "state": "running", "total_bytes_done": 0, "from": "", "rate": 0, "eta": 0, "error": "none", "progress": 0, "src": [ "/Disque dur/Photos/Launchpad/DSC_3491.jpg", "/Disque dur/Photos/Launchpad/DSC_3500.jpg" ], "dst": "/Disque dur/Photos/rockets.zip" } } ``` ##### Extract a file ###### `POST /fs/extract/` *permission `explorer` (inferred)* Request body (`application/json`): { src: string, dst: string, password: string, delete_archive: boolean, overwrite: boolean } Response `result`: FsTask Example request: ```http POST /api/v{version}/fs/extract/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```text { "src": "L0Rpc3F1ZSBkdXIvb2xkX2hkZC90ZXN0aXNvLjEuaXNv", /* /Disque dur/old_hdd/testiso.1.iso */ "dst": "L0Rpc3F1ZSBkdXIvb2xkX2hkZA==" /* /Disque dur/old_hdd */ "password": "", "delete_archive": false, "overwrite": true } ``` Example response: ```json { "success": true, "result": { "curr_bytes_done": 0, "total_bytes": 0, "nfiles_done": 0, "started_ts": 1355842252, "duration": 0, "done_ts": 0, "curr_bytes": 0, "type": "extract", "to": "/Disque dur/old_hdd", "id": 48, "nfiles": 0, "created_ts": 1355842252, "state": "running", "total_bytes_done": 0, "from": "/Disque dur/old_hdd/testiso.1.iso", "rate": 0, "eta": 0, "error": "none", "progress": 0, "src": [ "/Disque dur/old_hdd/testiso.1.iso" ], "dst": "/Disque dur/old_hdd" } } ``` ##### Repair a file ###### `POST /fs/repair/` *permission `explorer` (inferred)* Request body (`application/json`): { src: string, delete_archive: boolean } Response `result`: FsTask Example request: ```http POST /api/v{version}/fs/repair/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "src": "L0Rpc3F1ZSBkdXIvdGVzdHMvcGFyMi9saWNlbnNlLnR4dC5wYXIy", "delete_archive": false } ``` Example response: ```json { "success": true, "result": { "curr_bytes_done": 0, "total_bytes": 0, "nfiles_done": 0, "started_ts": 1355842559, "duration": 0, "done_ts": 0, "curr_bytes": 0, "type": "repair", "to": "", "id": 50, "nfiles": 0, "created_ts": 1355842559, "state": "running", "total_bytes_done": 0, "from": "", "rate": 0, "eta": 0, "error": "none", "progress": 0 } } ``` ##### Hash a file ###### `POST /fs/hash/` *permission `explorer` (inferred)* Request body (`application/json`): { src: string, hash_type: string } Response `result`: FsTask Example request: ```http POST /api/v{version}/fs/hash/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "src": "L0Rpc3F1ZSBkdXIvbXlfZmlsZQ==", "hash_type": "md5" } ``` Example response: ```json { "success": true, "result": { "curr_bytes_done": 0, "total_bytes": 4242, "nfiles_done": 0, "started_ts": 1355842559, "duration": 0, "done_ts": 0, "curr_bytes": 4242, "type": "hash", "to": "", "id": 50, "nfiles": 1, "created_ts": 1355842559, "state": "running", "total_bytes_done": 0, "from": "/Disque dur/my_file", "rate": 0, "eta": 0, "error": "none", "progress": 0 } } ``` ###### Get the hash value To get the hash, the task must have succeed and be in the state “done”. ###### `GET /fs/tasks/{id}/hash` *permission `explorer` (inferred)* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: { hash: string } Example request: ```http GET /api/v{version}/fs/tasks/50/hash HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "hash": "94baaad4d1347ec6e15ae35c88ee8bc8" } } ``` ##### Create a directory Contrary to other file system tasks, this operation is done synchronously. Instead of a returning a `FsTask` a call to this API will only return success status ###### `POST /fs/mkdir/` *permission `explorer` (inferred)* Request body (`application/json`): { parent: string, dirname: string } Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http POST /api/v{version}/fs/mkdir/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "parent": "L0Rpc3F1ZSBkdXI=", "dirname": "Test" } ``` Example response: ```json { "success": true } ``` ##### Rename a file/folder Contrary to other file system tasks, this operation is done synchronously. Instead of a returning a `FsTask` a call to this API will only return success status and the new path as a result ###### `POST /fs/rename/` *permission `explorer` (inferred)* Request body (`application/json`): { src: string, dst: string } Response `result`: string Example request: ```http POST /api/v{version}/fs/rename/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "src": "L0Rpc3F1ZSBkdXIvdGVzdC50eHQ=", "dst": "plop.txt" } ``` Example response: ```json { "success": true, "result": "L0Rpc3F1ZSBkdXIvcGxvcC50eHQ=" } ``` ##### Download a file ###### `GET /dl/{path}` *permission `explorer` (inferred)* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `path` | path | string | | Response: `application/octet-stream` Example request: ```http GET /api/v{version}/dl/L0Rpc3F1ZSBkdXIvUGhvdG9zL1BsYW5zIHNlY3JldHMuanBn HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: image/jpeg Content-Length: 600864 Content-Disposition: attachment; filename="Plans secrets.jpg" [ ... ] ``` ### File Sharing Link This API allows you to create a unique link to share content hosted on you Freebox. NOTE: this feature is available only if you enable HTTP remote access to your Freebox. #### File Sharing Errors When attempting to access the file sharing API, you may encounter the following errors: | error_code | Description | | --- | --- | | invalid_id | Invalid object id | | path_not_found | File or folder not found | | internal_error | Internal error | #### File Sharing Link object Share link have the following attributes: ##### Object `ShareLink` | Property | Type | Access | Description | | --- | --- | --- | --- | | `token` | string | read-only | The link unique sharing token | | `path` | string | read-only | The root path of the share, if the path is a regular file, only this file will be shared | | `name` | string | read-only | The readable name of the shared file/folder | | `expire` | integer (unix-time) | read-only | UNIX timestamp (seconds) Link expiration timestamp, 0 means no expiration. | | `fullurl` | string | read-only | Full URL to use for remote access. If remote access is disabled, the field will be empty. | #### File Sharing Link API ##### Retrieve a File Sharing link ###### `GET /share_link/` *permission `explorer` (inferred)* Returns the collection of all ShareLink Response `result`: ShareLink[] Example request: ```http GET /api/v{version}/share_link/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```text { success: true, result: [ { "path": "L0Rpc3F1ZSBkdXIvUGhvdG9zL01lcyB2YWNhbmNlcyBlbiByb3Vsb3R0ZQ==" /* /Disque dur/Photos/Mes vacances en roulotte */ "name": "Mes vacances en roulotte", "token": "gAnweF2Xg5OwcJWn", "expire": 1355852344, "fullurl": "http://13.37.42.69/api/v8/share/gAnweF2Xg5OwcJWn/" }, { "path": "L0Rpc3F1ZSBkdXIvc2hhcmVk", /* /Disque dur/shared */ "name": "shared", "token": "s8a+4VtOQNkkQ55f", "expire": 1355866268, "fullurl": "http://13.37.42.69/api/v8/share/s8a+4VtOQNkkQ55f/" } ] } ``` ###### `GET /share_link/{token}` *permission `explorer` (inferred)* Returns the ShareLink task with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `token` | path | string | | Response `result`: ShareLink Example request: ```http GET /api/v{version}/share_link/gAnweF2Xg5OwcJWn HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```text { "success": true, "result": { "path": "L0Rpc3F1ZSBkdXIvUGhvdG9zL01lcyB2YWNhbmNlcyBlbiByb3Vsb3R0ZQ==" /* /Disque dur/Photos/Mes vacances en roulotte */ "name": "Mes vacances en roulotte", "token": "gAnweF2Xg5OwcJWn", "expire": 1355852344, "fullurl": "http://13.37.42.69/api/v8/share/gAnweF2Xg5OwcJWn/" } } ``` ##### Delete a File Sharing link ###### `DELETE /share_link/{token}` *permission `explorer` (inferred)* Deletes the ShareLink task with the given token, if the task was running, stop it. No rollback is done, if a file as already been processed it will be left as is. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `token` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/share_link/gAnweF2Xg5OwcJWn HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Create a File Sharing link ###### `POST /share_link/` *permission `explorer` (inferred)* Create a new ShareLink Request body (`application/json`): ShareLink Response `result`: ShareLink Example request: ```http POST /api/v{version}/share_link/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "path": "L0Rpc3F1ZSBkdXIvVMOpbMOpY2hhcmdlbWVudHM=", "expire": 1355932880, "fullurl": "" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "path": "L0Rpc3F1ZSBkdXIvVMOpbMOpY2hhcmdlbWVudHM=", "name": "Téléchargements", "token": "6Hj57zgTfoQqb_vH", "expire": 1355932880, "fullurl": "http://13.37.42.69/api/v8/share/6Hj57zgTfoQqb_vH/" } } ``` ### File Upload This API allows you to upload files to the Freebox Server. NOTE: for large transfer files, you should prefer FTP over HTTP transfer *WARNING* the previous http upload method is now deprecated since api v4, you must now use the new WebSocket upload Api. If you can’t support WebSocket, you must use ftp for file transfer #### File Upload Errors When attempting to access the file upload API, you may encounter the following errors: | error_code | Description | | --- | --- | | invalid_request | Invalid request | | path_not_found | File or folder not found | | access_denied | Write permission denied in the destination folder | | destination_conflict | A file with same name already exists | | invalid_id | Invalid file upload id | | cancelled | Someone on a side channel as cancelled the upload | | noent | No upload with this id | #### File Upload object File uploads have the following attributes: ##### Object `FileUpload` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | read-only | upload id | | `size` | integer | read-only | Upload file size in bytes | | `uploaded` | integer | read-only | Uploaded bytes | | `status` | string | read-only | upload status can have the following values Values: `authorized` (Upload authorization is valid, upload has not started yet), `in_progress` (Upload in progress), `done` (Upload done), `failed` (Upload failed), `conflict` (Destination file conflict), `timeout` (Upload authorization is no longer valid), `cancelled` (Upload cancelled by user). | | `start_date` | integer (unix-time) | read-only | UNIX timestamp (seconds) upload start date | | `last_update` | integer (unix-time) | read-only | UNIX timestamp (seconds) last update of file upload object | | `upload_name` | string | read-only | name of the file uploaded | | `dirname` | string | read-only | upload destination directory | #### WebSocket File Upload API The file upload WebSocket path is /api/v8/ws/upload With this new API, the need for creating a ‘file upload authorization’ has now been removed. To be able to upload a file to the Freebox, you must open a WebSocket connection to the upload api, then for each file you want to upload you must : - send a `FileUploadStartAction` with the action ‘upload_start’ - wait for the associated `WebSocketResponse` that indicates success, then start transferring the file content by chunks, each chunk being a binary WebSocket frame. For each chunk you send, you’ll get a WsUploadProgress response indicating that the associated chunk has been received and processed. Note that you should not wait for this response before sending the next data chunk in order to get good bandwidth performance. - once all chunks have been transferred, you should send a `FileUploadFinalizeAction` with the action ‘upload_finalize’ and wait for the associated `WebSocketResponse` indicating success Note that if you have multiple files to send, you should reuse the same WebSocket connection, and repeat the upload steps again. If for any reason the WebSocket is closed during upload, the partially sent file will be left as-is on the Freebox to allow resuming upload at a later point. If you want to cancel an ongoing upload ou can send a `FileUploadCancelAction`. The partially uploaded file will then be deleted ##### File Upload Start Action ###### Object `FileUploadStartAction` | Property | Type | Access | Description | | --- | --- | --- | --- | | `request_id` | integer | | optional request_id | | `action` | string | | must be ‘upload_start’ | | `size` | integer | | optional file size | | `dirname` | string | | the destination directory (encoded value) | | `filename` | string | | the destination filename | | `force` | string | | select the way conflicts are handled Values: `missing` (The response to the FileUploadStartAction will be an error with ‘destination_conflict’ if the destination file already exists. The response will also contain a file_size attribute containing the existing file length (useful for resuming upload)), `overwrite` (If the target file already exists it will be overridden), `resume` (The upload will resume, all sent chunks will then be appended to the existing file.). | ##### File Upload Finalize action ###### Object `FileUploadFinalizeAction` | Property | Type | Access | Description | | --- | --- | --- | --- | | `request_id` | integer | | optional request_id | | `action` | string | | must be ‘upload_finalize’ | ##### File Upload Cancel action ###### Object `FileUploadCancelAction` | Property | Type | Access | Description | | --- | --- | --- | --- | | `request_id` | integer | | optional request_id | | `action` | string | | must be ‘upload_cancel’ | ##### File Upload Chunk File upload chunk are just Binary WebSocket frames containing raw file content. ##### File Upload Chunk Response For each received chunk, the Freebox will send a chunk response containing upload progress information the request_id used in response will be the one from the `FileUploadStartAction`, and ‘action’ value will be ‘upload_data’ ###### Object `FileUploadChunkResponse` | Property | Type | Access | Description | | --- | --- | --- | --- | | `total_len` | integer | | target file current length | | `complete` | boolean | | will be true in a reply to FileUploadFinalizeAction or FileUploadCancelAction | | `cancelled` | boolean | | will be true in a reply FileUploadCancelAction | ##### File Upload example ###### `GET /ws/upload` *permission `explorer` (inferred) · WebSocket upgrade* Start the WebSocket handshake: Client ==> Freebox Handshake response: Client <== Freebox Start upload: Client ==> Freebox Start upload response: Client <== Freebox Start upload with overwrite force mode: Client ==> Freebox Start upload response: Client <== Freebox Send data chunk: Client ==> Freebox [ BINARY WEBSOCKET FRAME MESSAGE containing file offset: 0, length: 512k ] [ BINARY WEBSOCKET FRAME MESSAGE containing file offset: 512k, length: 512k ] [ BINARY WEBSOCKET FRAME MESSAGE containing file offset: 1024k, length: 512k ] [ … ] Receive upload response: Client <== Freebox This will be received for each sent data chunk Send upload finalize: Client ==> Freebox Receive upload finalize confirmation: Client <== Freebox At this point you can start uploading a new file by repeating the previous steps starting from Start upload step Response: `101 Switching Protocols`. ```http GET ws://mafreebox.freebox.fr/api/v{version}/ws/upload HTTP/1.1 Host: mafreebox.freebox.fr Connection: Upgrade Upgrade: websocket Sec-WebSocket-Version: 13 Sec-WebSocket-Key: LhYCx4FBJE6pqrIL3tDC3g== X-Fbx-App-Auth: 35JYdQSvkcBYK84IFMU7H86clfhS75OzwlQrKlQN1gBch\/Dd62RGzDpgC7YB9jB2 ``` ```http HTTP/1.1 101 Switching Protocols Connection: upgrade Upgrade: websocket Sec-WebSocket-Accept: IqwCz8z8sON/eWQqkYKLu6iLkzo= ``` ```json { "action": "upload_start", "request_id": 3615, "size": 8526224, "dirname": "L0Rpc3F1ZSBkdXIvMF91cGxvYWRfdGVzdA==", "filename": "test_file.bin" } ``` ```json { "success": false, "action": "upload_start", "request_id": 3615, "msg": "Le fichier existe déjà", "file_size": 8526224, "error_code": "conflict" } ``` ```json { "action": "upload_start", "request_id": 6969, "size": 8526224, "dirname": "L0Rpc3F1ZSBkdXIvMF91cGxvYWRfdGVzdA==", "filename": "test_file.bin", "force": "overwrite" } ``` ```json { "action": "upload_start", "success": true, "request_id": 6969 } ``` ```text { "request_id": 6969 "action": "upload_data", "success": true, "result": { "total_len": 524288, "complete": false }, } { "request_id": 6969, "action": "upload_data", "success": true, "result": { "total_len": 1048576, "complete": false } } [ ... ] ``` ```json { "action": "upload_finalize", "request_id": 3615 } ``` ```json { "request_id": 3615, "action": "upload_finalize", "success": true, "result": { "total_len": 8526224, "complete": true } } ``` At this point you can start uploading a new file by repeating the previous steps starting from *Start upload* step #### Upload Progress tracking API ##### Get the list of uploads ###### `GET /upload/` *permission `explorer` (inferred)* Response `result`: FileUpload[] Example request: ```http GET /api/v{version}/upload/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "id": 1678139709, "size": 54960, "uploaded": 54960, "status": "done", "last_update": 1361465608, "start_date": 1361465608, "upload_name": "playlist.m3u", "dirname": "/Disque 1" } ] } ``` ##### Track an upload status ###### `GET /upload/{id}` *permission `explorer` (inferred)* With this API you can track the progress of your FileUpload task | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response `result`: FileUpload Example request: ```http GET /api/v{version}/upload/1678139709 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "id": 1678139709, "size": 54960, "uploaded": 54960, "status": "done", "last_update": 1361465608, "start_date": 1361465608, "upload_name": "playlist.m3u", "dirname": "/Disque 1" } } ``` ##### Cancel an upload ###### `DELETE /upload/{id}/cancel` *permission `explorer` (inferred)* Cancel the given FileUpload closing the connection The upload status must be in_progress | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/upload/136419941/cancel HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Delete an upload ###### `DELETE /upload/{id}` *permission `explorer` (inferred)* Delete the given FileUpload closing the connection if needed | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/upload/136419941 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ## Home ### Home API The Home API allows you to access features related to home automation #### List Home Adapters ##### Home Adapter Object ###### Object `HomeAdapter` HomeAdapter has the following attributes: | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | read-only | this object id | | `icon_url` | string | read-only | Url of the adapter icon | | `label` | string | read-only | The displayable name of this adapter | | `status` | string | | Adapter status Values: `unplugged` (The adapter is not available), `disabled` (The adapter has been disabled), `active` (the adapter is active). | | `type` | any | read-only | The technical type of this adapter. | | `props` | object | | Technical data related to this adapter, useful fo developers | ##### Get Home Adapters List ###### `GET /home/adapters` *permission `home` (inferred)* Retrieve the list of registered HomeAdapter. A new adapters appear when the user plugs a new home automation dongle. Response `result`: HomeAdapter[] Example request: ```http GET /api/v{version}/home/adapters HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "result": [ { "icon_url": "http://images.com/adapter_dm.png", "id": 1, "label": "Gestionnaire de caméra", "status": "active", "type": { "name": "adapter::cam" } }, { "icon_url": "http://images.com/adapter_dm.png", "id": 2, "label": "Réseau Rts", "status": "active", "type": { "name": "adapter::rts" } }, { "icon_url": "http://images.com/adapter_dm.png", "id": 3, "label": "Réseau IOHome", "props": { "Addr": 160, "SomfyId": "00:00:00:00" }, "status": "active", "type": { "name": "adapter::ios" } }, { "icon_url": "http://images.com/adapter_dm.png", "id": 4, "label": "Réseau Domus", "props": { "Network ID": 50791 }, "status": "active", "type": { "name": "adapter::domus" } } ], "success": true } ``` ##### Get a Home Adapter ###### `GET /home/adapters/{id}` *permission `home` (inferred)* Fetch information about a single HomeAdapter. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: HomeAdapter Example request: ```http GET /api/v{version}/home/adapters/1 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "result": { "icon_url": "http://images.com/adapter_dm.png", "id": 1, "label": "Gestionnaire de caméra", "status": "active", "type": { "name": "adapter::cam" } }, "success": true } ``` ##### Change a Home Adapter status ###### `PUT /home/adapters/{id}` *permission `home` (inferred)* Change the status of a HomeAdapter. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Request body (`application/json`): HomeAdapter Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http PUT /api/v{version}/home/adapters/1 HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "status": "disabled" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` #### Pair a new object ##### Pairing Step ###### Object `HomePairingStep` This represents a pairing process step. | Property | Type | Access | Description | | --- | --- | --- | --- | | `fields` | HomePairingStepField[] | read-only | A collection of ui elements to display. | | `icon_url` | string | read-only | The url of an image which represents this step. | | `pageid` | integer | read-only | The identifier of this step. | | `refresh` | integer | | The delay in millisecond after which to request a new step update. | | `session` | integer | read-only | The id of this session process. | ###### Object `HomePairingStepField` | Property | Type | Access | Description | | --- | --- | --- | --- | | `widget` | string | read-only | The type of ui element to display. Values: `label` (A simple text field), `select` (A selectable list item), `button` (A clickable button), `display_qrcode` (A qrcode), `input` (An input text field), `checkbox` (A checkable button), `progress` (A progress bar), `bar_button_left` (A button displayed at the left of the bottom nav bar), `bar_button_right` (A button displayed at the right of the bottom nav bar). | | `text` | string | read-only | The data to use with the displayed widget. Documented values: `label` (The label text), `select` (The item caption), `button` (The button caption), `display_qrcode` (The data to encode in the qrcode), `input` (The default text), `checkbox` (The button caption), `progress` (The progress value, in percent, as int), `bar_button_left` (The button caption), `bar_button_right` (The button caption). | ##### Start Pairing ###### `POST /home/pairing/{adapter_id}` *permission `home` (inferred)* **Start Pairing** Start the pairing process on a specific HomeAdapter. op: start type: the type of object to pair. This parameter is only relevant for the domus adapter. **Next Step** Send current step result and get the next step in the process. Call this when the user clicks on a button, bar_button_left, bar_button_right or a select item. field is a list of value corresponding to the current page widgets. **Stop Pairing** Stop the pairing process on a specific HomeAdapter. op: stop session: the id of the pairing session to stop | Parameter | In | Type | Description | | --- | --- | --- | --- | | `adapter_id` | path | integer | | Request body (`application/json`): HomeAdapter | { op: string, session: integer } Response `result`: any or HomePairingStep | type | Description | | --- | --- | | node::domus::freebox::secmod | Pair the security module | | node::domus::sercomm::pir | Pair a movement detector | | node::domus::sercomm::keyfob | Pair an alarm remote control | | node::domus::sercomm::doorswitch | Pair an opening detector | Example request: ```http POST /api/v{version}/home/pairing/1 HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "op": "start", "type": "node::domus::freebox::secmod" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Current Pairing Step ###### `GET /home/pairing/{adapter_id}` *permission `home` (inferred)* Get the current HomePairingStep on a specific HomeAdapter | Parameter | In | Type | Description | | --- | --- | --- | --- | | `adapter_id` | path | integer | | Response `result`: HomePairingStep Example request: ```http GET /api/v{version}/home/pairing/1 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "result": { "fields": [ { "text": "Veuillez vérifier que votre wifi est bien activé.", "widget": "label" } ], "icon_url": "/resources/images/home/pairing/wifi.png", "pageid": 2, "refresh": 1000, "session": 62328 }, "success": true } ``` ##### Next Step | widget | value in fields | | --- | --- | | label | null | | select | The index of the selected item, null if none selected | | button | true if the button has been clicked, false otherwise | | display_qrcode | null | | input | The text entered | | checkbox | true if checked, false otherwise | | progress | The progress value, in percent, as int | | bar_button_left | The button caption | | bar_button_right | The button caption | Example request: ```http POST /api/v{version}/home/pairing/1 HTTP/1.1 Host: mafreebox.freebox.fr ``` ```text { "op": "next", "session": "659887", "pageid": "1". "fields": [null,null,"mon texte", false, true] } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "result": { "fields": [ { "text": "Veuillez vérifier que votre wifi est bien activé.", "widget": "label" } ], "icon_url": "/resources/images/home/pairing/wifi.png", "pageid": 2, "refresh": 1000, "session": 62328 }, "success": true } ``` ##### Stop Pairing Example request: ```http POST /api/v{version}/home/pairing/1 HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "op": "stop", "session": 15645 } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` #### Home Nodes Acces objects connected to the automation network. ##### Home Node Object ###### Object `HomeNode` | Property | Type | Access | Description | | --- | --- | --- | --- | | `adapter` | integer | read-only | Id of the HomeAdapter this node is connected to. | | `category` | string | read-only | ??? | | `id` | integer | read-only | Id of this node. | | `label` | string | read-only | Displayable name of this node | | `name` | string | read-only | Technical name of this node | | `show_endpoints` | HomeNodeEndpoint[] | read-only | Endpoints exposed by this node | | `signal_links` | any[] | read-only | Links from other objects to this node signals | | `slot_links` | any[] | read-only | Links from other objects to this node slots | | `status` | string | read-only | Status of this node Values: `unreachable` (The adapter is not reachable), `disabled` (The node has been disabled), `active` (The node is connected), `unpaired` (The node has not been paired to any network). | | `type` | HomeNodeType | read-only | Node type info | ###### Object `HomeNodeEndpoint` | Property | Type | Access | Description | | --- | --- | --- | --- | | `category` | string | read-only | ??? | | `ep_type` | string | read-only | The endpoint type Values: `signal` (The endpoint outputs an information), `slot` (A endpoint that controls the object). | | `id` | integer | read-only | The endpoint id | | `visibility` | string | read-only | Visibility level of this endpoint Values: `internal` (For internal use only, never exposed), `normal` (The endpoint is available for scenarii but does not display info to the user), `dashboard` (The endpoint expose data that can be displayed on UI). | | `access` | string | read-only | Access mode of this endpoint Values: `r` (Read only), `w` (Write only), `rw` (Read and write). | ###### Object `HomeNodeType` | Property | Type | Access | Description | | --- | --- | --- | --- | | `icon` | string | read-only | The node icon name or url | | `label` | string | read-only | The node type technical name | | `physical` | boolean | read-only | True when the node is an actual connected object, false when it’s a virtual node | ###### Object `HomeNodeEndpointUi` | Property | Type | Access | Description | | --- | --- | --- | --- | | `display` | string | read-only | Display mode of this data Values: `text` (This displays the endpoint value as text. Read access is always allowed when “text” is used. When write access is allowed, the text may be editable on user request. When the “unit” entry is present and not null, it specifies the physical unit associated to the endpoint value.), `icon` (This displays the icon fetched from “icon_url” with % being replaced by the string representation of the endpoint value. For string value type, the % is replaced by the endpoint value. For int and float value types, this requires an “icon_ranges” array of threshold values. The % is replaced by the index in the “range” array which is just below the endpoint value. For boolean value type, the % is replaced by “on” or “off”. When the “value” is null, the % is replaced by the empty string. Read access is always allowed when “icon” is used. Write access is not used.), `button` (This displays a push button. Write access is always allowed when “button” is used. A null value must be send to the endpoint when pushed.), `slider` (This displays a slider with the cursor located according to the endpoint value in the range specified by “range”. Read access is always allowed when “slider” is used. When write access is allowed, the cursor may be moved by the user. When write access is not allowed it may be displayed as a progress bar.), `toggle` (This displays an on/off switch. Read access is always allowed when “switch” is used. When write access is allowed, switch may be toggled by the user. A boolean value must be send to the endpoint when toggled.), `color` (This displays a color value. The value type is an int representing the RGB color. Read access is always allowed when “color” is used.), `warning` (This display the icon fetched from “icon_url” when the value condition is true. For boolean value type, the value is the condition. For int and float value types, this requires a “range” of size 2. If the value is within the range, the condition is true.). | | `icon_url` | string | read-only | Url or name of the icon to display. The icon may be displayed for any value of “display”. | | `unit` | string | read-only | The unit of the value to display. | | `icon_color` | string | read-only | The hexadecimal presentation of the tint to apply to the icon fetched from “icon_url”. | | `text_color` | string | read-only | The hexadecimal presentation of the color of this endpoint label. | | `value_color` | string | read-only | The hexadecimal presentation of the color of this endpoint value. | | `range` | (number (double))[] | read-only | Range of array of threshold values for this endpoint value. | | `icon_color_range` | string[] | read-only | A range of colors to choose from instead of “icon_color”. The index in the range is the index in the “range” array which is just below the endpoint value. | | `text_color_range` | string[] | read-only | A range of colors to choose from instead of “text_color”. The index in the range is the index in the “range” array which is just below the endpoint value. | | `value_color_range` | string[] | read-only | A range of colors to choose from instead of “value_color”. The index in the range is the index in the “range” array which is just below the endpoint value. | | `status_text_range` | string[] | read-only | Text values to display instead of the value itself. The index in the range is the index in the “range” array which is just below the endpoint value. | ##### Get Home Nodes ###### `GET /home/nodes` *permission `home` (inferred)* Get the list of HomeNode A node is either a physical home automation device or a virtual black box used to interact with other nodes. Physical nodes are associated to an adapter. Nodes may have slot and signal endpoints. They can be used to interact with the node from the user interface. They can also be connected together using links. Response `result`: HomeNode[] Example request: ```http GET /api/v{version}/home/nodes HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [] } ``` ##### Get a Home Node ###### `GET /home/nodes/{id}` *permission `home` (inferred)* Get a specific HomeNode | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response `result`: HomeNode Example request: *The documentation example uses `GET /home/nodes`, which differs from the operation path.* ```http GET /api/v{version}/home/nodes HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```text { "success": true, "result": { [...] } } } ``` ##### Rename a Home Node ###### `PUT /home/nodes/{id}` *permission `home` (inferred)* Rename a HomeNode | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Request body (`application/json`): HomeNode Response: no result schema documented (envelope `{ "success": true }`). Example request: *The documentation example uses `PUT /home/nodes`, which differs from the operation path.* ```http PUT /api/v{version}/home/nodes HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "label": "Mon objet" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Delete a Home Node ###### `DELETE /home/nodes/{id}` *permission `home` (inferred)* Remove a HomeNode from the automation network. The object will need to be paired again if the node is physical. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). Example request: *The documentation example uses `DELETE /home/nodes`, which differs from the operation path.* ```http DELETE /api/v{version}/home/nodes HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` #### Home Nodes Values ##### Endpoint value object ###### Object `HomeNodeEndpointValue` | Property | Type | Access | Description | | --- | --- | --- | --- | | `value` | boolean \| integer \| number \| string \| null | read-only | Value typed by the endpoint value_type (bool, int, float, void) **Documentation contradiction:** Declared String while value_type documents bool/int/float/void. | | `unit` | string | read-only | The displayable unit of the value | | `refresh` | integer | read-only | The period this value need to be refreshed | | `value_type` | string | read-only | The type of value this endpoint expose Values: `bool`, `int`, `float`, `void`. | ##### Fetch Endpoint Value ###### `GET /home/endpoints/{node_id}/{endpoint_id}` *permission `home` (inferred)* Retrieve the current value of the specified node endpoint. The last pushed value is returned for slot endpoints. For signal endpoint, the value is retrieved directly from the node specific back-end. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `node_id` | path | integer | | | `endpoint_id` | path | integer | | Response `result`: HomeNodeEndpointValue Example request: ```http GET /api/v{version}/home/endpoints/14/1 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "result": { "value": false, "value_type": "bool" }, "success": true } ``` ##### Change Endpoint Value ###### `PUT /home/endpoints/{node_id}/{endpoint_id}` *permission `home` (inferred)* Push a value to the specified node slot endpoint. Only slot endpoint accept this operation. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `node_id` | path | integer | | | `endpoint_id` | path | integer | | Request body (`application/json`): { value: boolean | integer | number | string | null } Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http PUT /api/v{version}/home/endpoints/14/1 HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "value": true } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` #### Home Tileset The tileset is a user-friendly representation of connected objects which expose features instead of the actual objects ##### HomeTileObject ###### Object `HomeTile` | Property | Type | Access | Description | | --- | --- | --- | --- | | `node_id` | integer | read-only | Id of the HomeNode providing this tile data | | `label` | string | read-only | Displayable label of this tile | | `action` | string | read-only | Action provided by this tile Values: `tileset` (Open the related node sub-tileset), `graph` (Open a graph detail page), `store` (Display a store simple command), `store_slider` (Display a store slider command), `color_picker` (Display a color selection widget), `heat_picker` (Display a white tone selection widget), `intensity_picker` (Display an intensity selection widget), `none` (No action). | | `type` | string | read-only | The type of tile to display Values: `action` (A button tile that present no data), `info` (A generic tile that displays datas according to their UI field), `light` (A light control tile with color, intensity and head pickers), `alarm_sensor` (A tile representing a sensor that belongs to an alarm system), `alarm_control` (A tile representing an alarm system control), `camera` (A tile representing a camera). | | `group` | HomeNodeGroup | read-only | Displayable label of this tile | | `data` | HomeTileData[] | read-only | Displayable label of this tile | ###### Object `HomeNodeGroup` | Property | Type | Access | Description | | --- | --- | --- | --- | | `label` | string | read-only | The displayable name of this group | | `icon_url` | string | read-only | The icon url or name | ###### Object `HomeTileData` | Property | Type | Access | Description | | --- | --- | --- | --- | | `refresh` | integer | read-only | The period this data needs to be refreshed | | `label` | string | read-only | The displayable name of this data | | `ep_id` | integer | read-only | Id of the HomeNodeEndpoint related to this data | | `value_type` | string | read-only | The data value type Values: `bool`, `int`, `float`, `string`. | | `value` | string | read-only | The data value history as string in the format: “timestamp:value” separated by semicolons | | `ui` | HomeNodeEndpointUi | read-only | Ui descriptor for this data to know how to display it | ##### List all Tiles ###### `GET /home/tileset/all` *permission `home` (inferred)* Get the list of all tiles. Response `result`: HomeTile[] Example request: ```http GET /api/v{version}/home/tileset/all HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "result": [ { "data": [ { "ep_id": 0, "label": "Trigger", "ui": { "access": "rw", "display": "text" }, "value": null, "value_type": "void" }, { "category": "alarm", "ep_id": 1, "label": "Alarme", "ui": { "access": "rw", "display": "toggle", "icon_url": "http://lagabardine.ovh/~jeremie/img/Alarm.png" }, "value": false, "value_type": "bool" }, { "ep_id": 2, "label": "Pin Code", "ui": { "access": "rw", "display": "text" }, "value": 0, "value_type": "int" }, { "ep_id": 3, "label": "Sirène", "refresh": 2000, "ui": { "access": "r", "display": "toggle", "icon_url": "http://lagabardine.ovh/~jeremie/img/Alarm.png" }, "value": false, "value_type": "bool" } ], "ep_type": "slot", "group": { "icon_url": "http://lagabardine.ovh/~jeremie/img/favori.png", "label": "" }, "node_id": 17, "type": "alarm_control" }, { "data": [ { "ep_id": 0, "history": "1539868875260:1;1539876788228:0;1539876788530:1;1539876788796:0;1539876788850:1;1539876798829:0;1539876799143:1;1540282834199:1;1540305925367:0;1540305930508:1;", "label": "Fenêtre", "ui": { "access": "r", "display": "icon", "icon_color_range": [ "#ff0000", "#00ff00" ], "icon_url": "home_picto_dws", "status_text_range": [ "Ouvert", "Fermé" ], "value_color": "#00ff00" }, "value": null, "value_type": "bool" }, { "ep_id": 1, "history": "", "label": "Couvercle", "ui": { "access": "r", "display": "warning", "icon_color": "#00ff00", "icon_url": "home_picto_cover_alert" }, "value": null, "value_type": "bool" }, { "ep_id": 2, "label": "Niveau de Batterie", "ui": { "access": "r", "display": "warning", "icon_color": "#00ff00", "icon_url": "home_picto_battery_alert", "range": [ 0, 10 ], "unit": "%" }, "value": null, "value_type": "int" } ], "ep_type": "signal", "group": { "icon_url": "http://lagabardine.ovh/~jeremie/img/favori.png", "label": "alarm" }, "label": "Détecteur d'ouvertures", "node_id": 24, "type": "alarm_sensor" }, { "data": [ { "ep_id": 0, "history": "1539597596899:1;1539867684806:1;1539868117300:0;1539868164089:1;1540282931546:1;1540296461125:0;1540296468385:1;", "label": "Détection", "ui": { "access": "r", "display": "icon", "icon_color_range": [ "#ff0000", "#00ff00" ], "icon_url": "home_picto_pir", "status_text_range": [ "Mouvement détecté", "Aucun movement" ], "unit": "" }, "value": null, "value_type": "bool" }, { "ep_id": 1, "history": "", "label": "Couvercle", "ui": { "access": "r", "display": "warning", "icon_url": "home_picto_cover_alert", "unit": "" }, "value": null, "value_type": "bool" }, { "ep_id": 2, "label": "Niveau de Batterie", "ui": { "access": "r", "display": "warning", "icon_url": "home_picto_battery_alert", "range": [ 0, 10 ], "unit": "%" }, "value": null, "value_type": "int" } ], "ep_type": "signal", "group": { "icon_url": "http://lagabardine.ovh/~jeremie/img/favori.png", "label": "alarm" }, "label": "move", "node_id": 26, "type": "alarm_sensor" } ], "success": true } ``` ##### List a Node sub-tileset ###### `GET /home/tileset/{node_id}` *permission `home` (inferred)* Get the list of all tiles corresponding to a node with “action”=”tileset”. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `node_id` | path | integer | | Response `result`: any[] Example request: ```http GET /api/v{version}/home/tileset/42 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [] } ``` ### Special Tiles specification #### Alarm Tiles ##### Alarm control This tile gives the current state of the alarm and allow to turn it on an off type alarm_control data Index Value type Access Description 0 enum r The current alarm state 1 void w Activate the main alarm 2 void w Activate the night alarm 3 void w Deactivate the alarm 4 void w Skip the alarm activation timer 5 int r/w Alarm PIN code that should be asked before changing the alarm state 6 string r Alarm error code state values State Description idle The alarm is off alarm1_arming The main alarm is being activated, it’s a countdown when only the sensors not in the timed zone can trigger the alert alarm2_arming The night alarm is being activated, it’s a countdown when only the sensors not in the timed zone can trigger the alert alarm1_armed The main alarm is on alarm2_armed The night alarm is on alarm1_alert_timer The main alarm has been triggered by a sensor in the timed zone and the siren will ring after a countdown alarm2_alert_timer The night alarm has been triggered by a sensor in the timed zone and the siren will ring after a countdown alert The siren is ringing ##### Alarm sensor This tile represents a connected sensor used to trigger the alarm type alarm_sensor data Index Value type Access Description 0 boolean r The state of this sensor: false=opening detected 1..n *any* r Any data with *warning* display type ##### Alarm sensor This tile represents a connected sensor used to trigger the alarm type alarm_sensor data Index Value type Access Description 0 boolean r The state of this sensor: false=opening detected 1..n *any* r Any data with *warning* display type ##### Camera This tile represents a camera type camera data Index Value type Access Description 0 string r The url of this camera on the local network #### Automation tiles ##### Simple store This tile represents a store with simple commands type info action store data Index Value type Access Description 0 boolean r The state of the store: true=open, false=closed, null=undetermined 1 void w Command to open the store 2 void w Command to stop the store at its current position 3 void w Command to close the store ##### Commanded store This tile represents a store with precise position command type info action store_slider data Index Value type Access Description 0 int rw The position of store in percent: 0=fully opened, 100=fully closed 1 void w Command to stop the store at its current position ##### Color light bulb This tile represents a connected light bulb with full color and intensity control type light action color_picker data Index Value type Access Description 0 void rw The state of the light: true=on 1 int rw The H and S components of the color HSV value (H: 16 bits, S: 8 bit) 2 int rw The V value of the color HSV value (V: 8 bits) ##### White light bulb This tile represents a connected light bulb with intensity and white tone control only type light action heat_picker data Index Value type Access Description 0 void rw The state of the light: true=on 1 int rw The H and S components of the color HSV value (H: 16 bits, S: 8 bit) 2 int rw The V value of the color HSV value (V: 8 bits) ##### Luminosity light bulb This tile represents a connected light bulb with intensity control only type light action intensity_picker data Index Value type Access Description 0 void rw The state of the light: true=on 1 int rw The luminosity value in percent ### Cameras The Camera API allows you to access features related to cameras. #### Camera Errors When attempting to access the Camera API, you may encounter the following errors: | error_code | Description | | --- | --- | | noent | no camera with this id | | inval | invalid parameters | #### Camera object Camera object have the following properties ##### Object `Camera` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | string | | camera id | | `node_id` | integer | | camera node id | | `name` | string | | camera name | | `stream_url` | string | | camera stream url | | `lan_gid` | string | | camera lan id | #### Camera API ##### Get list of cameras ###### `GET /camera/` *permission `camera` (inferred)* Returns the collection of all Camera Response `result`: Camera[] Example request: ```http GET /api/v{version}/camera/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "id": "012345678901", "node_id": 0, "name": "Caméra du salon", "stream_url": "/camera/stream/012345678901/stream.m3u8", "lan_gid": "ether-3c:98:72:fa:36:15" }, { "id": "012345678902", "node_id": 1, "name": "Caméra du bureau", "stream_url": "/camera/stream/012345678902/stream.m3u8", "lan_gid": "ether-3c:98:72:fa:42:58" } ] } ``` ##### Access a given camera ###### `GET /camera/{id}` *permission `camera` (inferred)* Returns the Camera with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response `result`: Camera Example request: ```http GET /api/v{version}/camera/012345678901 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "id": "012345678901", "node_id": 0, "name": "Caméra du salon", "stream_url": "/camera/stream/012345678901/stream.m3u8", "lan_gid": "ether-3c:98:72:fa:36:15" } } ``` ##### Delete a camera Use Home Node Api to delete camera (like a node) with its node id ## Language ### Language support With this API you can fetch the list of supported languages on the Freebox, and change the current language. #### Language support Object ##### Object `LanguageSupport` Currently configured language. List of supported languages, in iso 639-3 (alpha-3) format, used for changing the language. | Property | Type | Access | Description | | --- | --- | --- | --- | | `lang` | string | | | | `avalaible` | string[] | read-only | | #### Get language status ##### `GET /lang/` Get the current language in iso 639-3 (alpha-3) format, as well as the list of supported languages. Response `result`: { lang: string, avalaible: string[] } Example request: ```http GET /api/v{version}/lang HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "lang": "fra", "avalaible": [ "fra", "eng" ] } } ``` #### Set language ##### `POST /lang/` *permission `settings` (inferred)* Set the current language. Request body (`application/json`): { lang: string } Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http POST /api/v{version}/lang HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "lang": "eng" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ## Notification ### Notif The Notification API allows you to access features related with notification, #### Notification Errors When attempting to access the Notification API, you may encounter the following errors: | error_code | Description | | --- | --- | | noent | no device with this id | | inval | invalid parameters | #### Notification Target object Target Notification Target object have the following properties ##### Object `NotificationTarget` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | string | | device unique id | | `last_use` | integer | | | | `type` | string | | ios \| android \| firebase | | `name` | string | | device name | | `api_url` | string | | url of the notification server used to handle communication with the devices | | `message_type` | string | | notification message type Documented values: `data` (only send the notification payload to the device), `notification` (send the notification payload along a notification title and body to the device). | | `subscriptions` | any[] | | permission list array Documented values: `phone` (notification when missing call), `download` (notification when download is finished), `security` (notification when alarm is on), `box_state` (notification when box state changed), `lan_host` (notification related to lan events), `password_change` (notification when admin password is changed). | #### Notification API ##### Get list of notification target ###### `GET /notif/targets` Returns the collection of all Notification Target Response `result`: NotificationTarget[] Example request: ```http GET /api/v{version}/notif/targets HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```text { "success":true, "result":[ { "last_use":0, "type":"ios", "name":"iPhone de Xavier", "id":"11111111-2222-3333-4444-555555555555", "subscriptions":[ "security", "downloader", "phone", ], "api_url": "https://monserver.example.com/mon_app", "message_type": "notification" }, { "last_use":0, "type":"android", "name":"mamy", "id":"22222222-1111-3333-4444-555555555555", "subscriptions":[ "phone" ], "api_url": "https://monserver.example.com/mon_app", "message_type": "notification" ] } ``` ##### Get a given notification target by this id ###### `GET /notif/targets/{id}` Returns the Notification Target with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response `result`: NotificationTarget[] Example request: ```http GET /api/v{version}/notif/targets/11111111-2222-3333-4444-555555555555 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "last_use": 0, "type": "ios", "name": "iPhone de Xavier", "id": "11111111-2222-3333-4444-555555555555", "subscriptions": [ "security", "downloader", "phone" ], "api_url": "https://monserver.example.com/mon_app", "message_type": "notification" } ] } ``` ##### Delete a notification target ###### `DELETE /notif/targets/{id}` Deletes the Notification Target with the given id. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/notif/targets/22222222-1111-3333-4444-555555555555 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Update a notification target ###### `PUT /notif/targets/{id}` Update the Notification Target with the given id. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Request body (`application/json`): NotificationTarget Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http PUT /api/v{version}/notif/targets/22222222-1111-3333-4444-555555555555 HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "name": "iPhone de Xavier", "type": "ios", "token": "token_token_token_token_token_token_token", "subscriptions": [ "download", "phone" ], "api_url": "https://monserver.example.com/mon_app", "message_type": "notification" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Add a notification target ###### `POST /notif/targets/` Create an new Notification Target. Request body (`application/json`): NotificationTarget Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http POST /api/v{version}/notif/targets/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "name": "iPhone de Xavier", "type": "ios", "token": "token_token_token_token_token_token_token", "subscriptions": [ "download", "phone" ], "api_url": "https://monserver.example.com/mon_app", "message_type": "notification" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ### Notification server specification When a notification should be sent, the Freebox will use this API on the address specified in the notification target. Your server must implement this API contract : #### `POST /register` A new target has been registered ```json { "box_id": "", "device_type": "ios|android|firebase", "token": "", "device_name": "", "device_id": "" } ``` #### `DELETE /register/{box_id}/{device_id}` A target has been deleted #### `POST /send` Send a notification Response : This API send back the device ids in two lists : failure and success ```json { "devices": [ "", "", "" ], "title": "", "body": "", "payload": {}, "box_id": "" } ``` ```json { "failureIds": [ "device_id_1", "device_id_2" ], "successIds": [ "device_id_3" ] } ``` ### Notifications specification Notifications sent to registered devices has a payload depending on notification type : #### Object `downloader` | Property | Type | Access | Description | | --- | --- | --- | --- | | `box_id` | string | | ID of the box that sent the notification | | `type` | string | | Notification type : downloader | | `data` | integer | | ID of the download task that triggered the notification | | `event` | string | | Downloader event that triggered the notification Values: `task_done` (The download task is complete), `task_error` (The download task has failed), `task_seeding_done` (The download task seeding is complete). | #### Object `phone` | Property | Type | Access | Description | | --- | --- | --- | --- | | `box_id` | string | | ID of the box that sent the notification | | `type` | string | | Notification type : phone | | `data` | CallEntry | | Call object that triggered the notification | | `event` | string | | Phone event that triggered the notification Values: `missed_call` (A call has been missed). | #### Object `box_state` | Property | Type | Access | Description | | --- | --- | --- | --- | | `box_id` | string | | ID of the box that sent the notification | | `type` | string | | Notification type : box_state | | `event` | string | | Box state event that triggered the notification Values: `pub_up` (Wan public connection went up), `enter_sleep` (Box will enter sleep mode), `shut_down` (Box will shut down), `reboot` (Box will reboot). | #### Object `lan_host` | Property | Type | Access | Description | | --- | --- | --- | --- | | `box_id` | string | | ID of the box that sent the notification | | `type` | string | | Notification type : lan | | `host_id` | string | | ID of the host that triggered the notification | | `interface` | string | | The LAN interface the host is connected to | | `event` | string | | LAN host event that triggered the notification Values: `first_connection` (The device is connected for the first time). | #### Object `password_change` | Property | Type | Access | Description | | --- | --- | --- | --- | | `box_id` | string | | ID of the box that sent the notification | | `type` | string | | Notification type : password_change | | `ip` | string | | IP of the lan host that requested password change | ## Parental filter ### Profile management #### Profile Object ##### Object `Profile` unique id of this profile name of this profile URL of the icon relative to root of the API domain. | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | read-only | | | `name` | string | | | | `icon` | string | | | #### Profiles API ##### Get the list of profiles ###### `GET /profile` *permission `profile` (inferred)* Response `result`: { id: integer, name: string, url: string }[] Example request: ```http GET /api/v{version}/profile HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "id": 2, "name": "r0ro", "url": "/resources/images/profile/profile_04.png" }, { "id": 7, "name": "Xav", "url": "/resources/images/profile/profile_02.png" } ] } ``` ##### Get a profile ###### `GET /profile/{id}` *permission `profile` (inferred)* Get the Profile with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: Profile Example request: ```http GET /api/v{version}/profile/2 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "id": 2, "name": "r0ro", "url": "/resources/images/profile/profile_04.png" } } ``` ##### Add a profile ###### `POST /profile/` *permission `profile` (inferred)* Request body (`application/json`): { name: string, url: string } Response `result`: { id: integer } Example request: ```http POST /api/v{version}/profile HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "name": "Pierrot", "url": "/resources/images/profile/profile_04.png" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "id": 3 } } ``` ##### Delete a profile ###### `DELETE /profile/{id}` *permission `profile` (inferred)* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/profile/2 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Update a profile ###### `PUT /profile/{id}` *permission `profile` (inferred)* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Request body (`application/json`): { name: string, url: string } Response `result`: { id: integer, name: string, url: string } Example request: *The documentation example uses `PUT /profile`, which differs from the operation path.* ```http PUT /api/v{version}/profile HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "name": "Pierrot", "url": "/resources/images/profile/profile_02.png" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "id": 3, "name": "Pierrot", "url": "/resources/images/profile/profile_02.png" } } ``` #### Network Control Object The different modes supported are : | mode | Description | | --- | --- | | allowed | access is allowed | | denied | access is denied | | webonly | access is granted only for HTTP and HTTPS traffic; legacy mode, use not recommended. | ##### Object `NetworkControl` Id of the profile this network control is associated with. This is read-only, unless you use the POST api to add a network control. UNIX timestamp of next rule change in seconds. 0 if no next change. mode of current override. mode in use. If override is true, it will be override_mode, otherwise it’s the mode from the rules attached to this NetworkControl. mode that would be in use if there was no override. Depends only on rules, and is useful to determine what will happen when override is lifted. Unix timestamp in seconds when override ends. Relevant when override is true. Set at 0 for unlimited. Whether there’s an override at the moment. List of mac adresses associated with this profile’s network control. List of Lan Host objects associated with this profile’s network control. Derived from the macs array. Control resolution per day of this network control. Currently at 288. list of custom day range, each custom day range represents a group of days for which you want to use a different planning than other week days. For instance a custom day range can contain the list of your children holidays. each cdayranges can be a coma separated list of cdayranges, for instance “:fr_bank_holidays,:fr_school_holidays_b” | Property | Type | Access | Description | | --- | --- | --- | --- | | `profile_id` | integer | read-only | | | `next_change` | integer | read-only | | | `override_mode` | string | | | | `current_mode` | string | read-only | | | `rule_mode` | string | read-only | | | `override_until` | integer | | | | `override` | boolean | | | | `macs` | string[] | | | | `hosts` | LanHost[] | read-only | | | `resolution` | integer | read-only | | | `cdayranges` | string[] | | | #### Network Control API ##### Get Network Control for all profiles ###### `GET /network_control` *permission `profile` (inferred)* Response `result`: NetworkControl[] ##### Get Network Control for a profile ###### `GET /network_control/{profile_id}` *permission `profile` (inferred)* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `profile_id` | path | integer | | Response `result`: NetworkControl Example request: ```http GET /api/v{version}/network_control/5 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "profile_id": 5, "next_change": 0, "override": false, "override_mode": "denied", "current_mode": "allowed", "macs": [ "D8:A2:CA:FE:BA:DF", "D0:23:BE:DE:AD:EF" ], "hosts": [ "PC-de-mamie", "Cantal-chromebook" ], "resolution": 288, "cdayranges": [] } } ``` ##### Update Network Control for a profile ###### `PUT /network_control/{profile_id}` *permission `profile` (inferred)* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `profile_id` | path | integer | | Request body (`application/json`): NetworkControl Response `result`: NetworkControl Example request: ```http PUT /api/v{version}/network_control/3 HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "profile_id": 3, "next_change": 0, "override": false, "override_mode": "allowed", "current_mode": "denied", "macs": [ "98:E8:FA:FE:BA:42", "2C:CC:44:D1:AD:4F" ], "hosts": [ "3DS-Thibault", "Vita-Rodolphe" ], "resolution": 288, "cdayranges": [] } ``` Example response: ```json { "success": true, "result": { "profile_id": 3, "next_change": 0, "override": false, "override_mode": "allowed", "current_mode": "denied", "macs": [ "98:E8:FA:FE:BA:42", "2C:CC:44:D1:AD:4F" ], "hosts": [ "3DS-Thibault", "Vita-Rodolphe" ], "resolution": 288, "cdayranges": [] } } ``` ##### Get migration to new default mode status Verify if migration to new default mode has been done (“allowed” only) if default mode was modified. ###### `GET /network_control/migrate` *permission `profile` (inferred)* Response `result`: { default_mode_migrated: boolean } Example request: ```http GET /api/v{version}/network_control/migrate HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "default_mode_migrated": false } } ``` ##### Migrate to new default mode Do migration to new default mode (“allowed”) if it was modified previously. ###### `POST /network_control/migrate` *permission `profile` (inferred)* Response `result`: { default_mode_migrated: boolean } Example request: ```http POST /api/v{version}/network_control/migrate HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "default_mode_migrated": true } } ``` #### Rule Object ##### Object `NetworkControlRule` Unique rule identifier. Id of profile this rule applies to. Rule name Mode described in Network Control Object Seconds since start of day (00:00) when rule starts. Must be in increments of the resolution. When resolution is 288, it means 5 minutes slots, so the value must be a multiple of 300. Time of day in seconds since start of day (00:00) when rule ends. end_time modulo 300 must always be zero when resolution is 288. Array of days of weeks when this rule apply. 8th one is for cdayranges. Whether rule is enabled. | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | read-only | | | `profile_id` | integer | read-only | | | `name` | string | | | | `mode` | string | | | | `start_time` | any | | | | `end_time` | any | | | | `weekdays` | boolean[] | | | | `enabled` | boolean | | | #### Rule API ##### Get Network Control Rules for a profile ###### `GET /network_control/{profile_id}/rules` *permission `profile` (inferred)* Returns the list of rules for this profile | Parameter | In | Type | Description | | --- | --- | --- | --- | | `profile_id` | path | string | | Response `result`: NetworkControlRule[] ##### Get a Network Control Rule ###### `GET /network_control/{profile_id}/rules/{rule_id}` *permission `profile` (inferred)* Returns one rule. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `profile_id` | path | string | | | `rule_id` | path | string | | Response `result`: NetworkControlRule ##### Create a Network Control Rule ###### `POST /network_control/{profile_id}/rules/` *permission `profile` (inferred)* Create a rule given in parameter. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `profile_id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). ##### Update a Network Control Rule ###### `PUT /network_control/{profile_id}/rules/{rule_id}` *permission `profile` (inferred)* Update rule. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `profile_id` | path | string | | | `rule_id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). ##### Delete a Network Control Rule ###### `DELETE /network_control/{profile_id}/rules/{rule_id}` *permission `profile` (inferred)* Delete rule. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `profile_id` | path | string | | | `rule_id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). ## Player devices ### Player [UNSTABLE] **\*** INTERNAL USE ONLY **\*** With the player API you access and control a Freebox Player connected on the same local network as the Freebox Server. Available players can be enumerated, and the listed player identifier can be used to dispatch commands. #### Player Errors When attempting to access the player API, you may encounter the following errors: | error_code | Description | | --- | --- | | internal_error | Internal error | | inval | Invalid parameters | | noent | no player with this id | #### Player Objects ##### Player ###### Object `Player` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | | | | `device_name` | string | | | | `uid` | string | | | | `reachable` | boolean | | | | `api_version` | string | | | | `api_available` | boolean | | | ##### Player Status Foreground App ###### Object `PlayerStatusForegroundApp` | Property | Type | Access | Description | | --- | --- | --- | --- | | `package_id` | integer | | | | `cur_url` | string | | | | `context` | object | | | | `package` | string | | | ##### Player Status Capabilities Capabilities of a media player. ###### Object `PlayerStatusCapabilities` | Property | Type | Access | Description | | --- | --- | --- | --- | | `play` | boolean | | | | `pause` | boolean | | | | `stop` | boolean | | | | `next` | boolean | | | | `prev` | boolean | | | | `record` | boolean | | | | `record_stop` | boolean | | | | `seek_forward` | boolean | | | | `seek_backward` | boolean | | | | `seek_to` | boolean | | | | `shuffle` | boolean | | | | `repeat_all` | boolean | | | | `repeat_one` | boolean | | | | `select_stream` | boolean | | | | `select_audio_track` | boolean | | | | `select_srt_track` | boolean | | | ##### Player Status Informations ###### Object `PlayerStatusInformations` | Property | Type | Access | Description | | --- | --- | --- | --- | | `name` | string | | | | `last_activity` | integer (int64) | | | | `capabilities` | PlayerStatusCapabilities | | | ##### Player Status ###### Object `PlayerStatus` | Property | Type | Access | Description | | --- | --- | --- | --- | | `power_state` | string | | | | `player` | PlayerStatusInformations | | State of the active media player on the device. | | `foreground_app` | PlayerStatusForegroundApp | | The context of the currently running application. The fields exposed in this object are left to the discretion of the application author, and thus subject to change at any time. | #### Player API ##### List every player devices ###### `GET /player` *permission `player` (inferred) · unstable* Returns the list of all player devices registered on the local network ([Player]). Response `result`: Player[] Example request: ```http GET /api/v{version}/player HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "device_name": "Freebox Player", "stb_type": "stb_v7", "uid": "123456789012345678911234567892123", "reachable": true, "api_version": "6.0", "id": 11, "api_available": true } ] } ``` ##### Get player device status ###### `GET /player/{id_player}/api/v6/status/` *permission `player` (inferred) · unstable* Returns the current state of a player device (Player). | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id_player` | path | integer | | Response `result`: { power_state: string } Example request: ```http GET /api/v{version}/player/11/api/v6/status/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "power_state": "standby" } } ``` ##### Control the active media player of a device ###### `POST /player/{id_player}/api/v6/control/mediactrl/` *permission `player` (inferred) · unstable* Send a command to the active media player of a device. Not all commands are always available, the capabilities of the active media player can be retrieved in the device status to determine which commands ca be used. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id_player` | path | integer | | Request body (`application/json`): { cmd: string } Response: no result schema documented (envelope `{ "success": true }`). | command | Description | | --- | --- | | play_pause | toggle play pause | | stop | stop | | prev | previous | | next | next | | select_stream | select quality of the stream | | select_audio_track | select audio track | | select_srt_track | select subtitle track | Example request: ```http POST /api/v{version}/player/11/api/v6/control/mediactrl/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "cmd": "play_pause" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Control the playback volume of the device ###### `GET /player/{id_player}/api/v6/control/volume/` *permission `player` (inferred) · unstable* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id_player` | path | integer | | Response `result`: { mute: boolean, volume: integer } Example request: ```http GET /api/v{version}/player/11/api/v6/control/volume/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "mute": false, "volume": 25 } } ``` ###### `PUT /player/{id_player}/api/v6/control/volume/` *permission `player` (inferred) · unstable* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id_player` | path | string | | Request body (`application/json`): { volume: integer, mute: boolean } Response `result`: { mute: boolean, volume: integer } Example request: ```http PUT /api/v{version}/player/{id_player}/api/v6/control/volume/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "volume": 50 } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "mute": false, "volume": 50 } } ``` ##### Open a url on a player device ###### `POST /player/{id_player}/api/v6/control/open` *permission `player` (inferred) · unstable* Here are some useful examples calls: Open the video player: { "url": "http://jell.yfish.us/media/jellyfish-3-mbps-hd-h264.mkv", "type": "video/x-matroska" } Open the web browser: { "url": "https://www.google.com", "type": "text/html" } Open TV on channel 2: { "url": "tv:?channel=2" } Open a YouTube video: { "url": "https://www.youtube.com/watch?v=pltY5vS-aOY" } | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id_player` | path | integer | | Request body (`application/json`): { url: string, type: string } Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http POST /api/v{version}/player/11/api/v6/control/open HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "url": "tv:?channel=123" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ## PVR ### PVR [UNSTABLE] **\*** INTERNAL USE ONLY **\*** #### PVR Errors | error_code | Description | | --- | --- | | noent | wrong id | | inval | invalid params | | inval_date_fmt | invalid date format | | inval_end_before_start | start time must be before end time | | system_time_incorrect | system time not available | | record_duration_too_long | record duration is too long | | record_date_in_past | record date is already passed | | unknown_channel | unknown channel | | no_channel_svc | no service for this channel | | only_auto_disable | can’t disable manual precord | | cannot_change_en_state | can’t change enabled state | | cannot_disable_has_data | can’t disable started record | | internal_error | internal error | #### PVR Config PVR config has the following attributes: ##### Object `PvrConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `margin_before` | integer | | default margin before recording start time | | `margin_after` | integer | | default margin after recording end time | #### PVR Config API ##### Get the current PVR configuration ###### `GET /pvr/config/` *permission `pvr` (inferred) · unstable* Returns the current PvrConfig Response `result`: PvrConfig Example request: ```http GET /api/v{version}/pvr/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "margin_before": 10, "margin_after": 5 } } ``` ##### Update the current PVR configuration ###### `PUT /pvr/config/` *permission `pvr` (inferred) · unstable* Update the current PvrConfig Request body (`application/json`): PvrConfig Response `result`: PvrConfig #### PVR Quota PVR Quota has the following attributes: ##### Object `PvrQuota` | Property | Type | Access | Description | | --- | --- | --- | --- | | `quota_exceeded` | boolean | | is quota exceeded | | `needed_tresh` | integer | | needed quota threshold | | `cur_tresh` | integer | | current quota threshold | #### PVR Quota API ##### Getting the current quota info ###### `GET /pvr/quota/` *permission `pvr` (inferred) · unstable* Response `result`: PvrQuota Example request: ```http GET /api/v{version}/pvr/quota/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "quota_exceeded": true, "needed_tresh": 80, "cur_tresh": 40 } } ``` ##### Request next quota threshold ###### `PUT /pvr/quota/` *permission `pvr` (inferred) · unstable* Request next quota threshold. You don’t have to provide any arguments, the quota will be adjusted automatically if needed. Request body (`application/json`): object Response `result`: PvrQuota Example request: ```http PUT /api/v{version}/pvr/quota/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json {} ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "quota_exceeded": false, "needed_tresh": 80, "cur_tresh": 80 } } ``` ### PVR Programmed records Precords (Programmed records) are records that are planned. Precords can be manual, or generated using a PVR Generator (see below). Only manual Precords can be edited directly. #### Precord Precord has the following attributes: ##### Object `Precord` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | string | read-only | precord id | | `media` | string | | media name on which the record will be written to. See the Media API for more info. This property and can be empty when the file backing the record is not available, for example when secure is set. | | `path` | string | | destination directory on the media storage where the record will be written to | | `has_record_gen` | boolean | read-only | if true, this precord has been generated using a Generator | | `record_gen_id` | integer | read-only | if has_record_gen, this is the id of the generator | | `conflict` | boolean | read-only | if true this record may conflict with another record | | `overlap_list` | integer[] | read-only | in case of conflict, this will contain the list of records id that may conflict with this record | | `enabled` | boolean | | it only applies to generated records. If false the generated precord will be skipped. | | `altered` | boolean | read-only | a precord is altered when some part of the recording may be missing. This can be the case if a conflict occurred during the recording (or connection was down) | | `state` | string | read-only | Values: `disabled` (disabled), `start_error` (failed to start), `waiting_start_time` (scheduled), `starting` (starting), `running` (running), `running_error` (running with error), `failed` (failed), `finished` (finished). | | `error` | string | read-only | Values: `none`, `file_access_error`, `disk_full`, `private_but_no_private_dir`, `network_problem`, `resource_problem`, `no_stream_available`, `no_data_received`, `missed`, `stopped`, `internal_error`, `unknown_error`. | | `channel_uuid` | string | | channel uuid | | `channel_name` | string | | optional channel name | | `channel_quality` | string | | Values: `auto`, `hd`, `sd`, `ld`, `3d`. | | `channel_type` | string | | Values: `` (auto), `iptv` (use only iptv streams), `dvb` (use only dvb streams). | | `name` | string | | record name | | `subname` | string | | record subname | | `broadcast_type` | string | | Values: `tv`, `radio`. | | `start` | integer | | record start timestamp | | `end` | integer | | record end timestamp | | `legacy_uri` | string | | only used for legacy apps. Use channel_uuid instead when available NOTE: only visible when called from player | | `force_channel_name` | string | | only used for legacy apps. Use channel_uuid instead when available NOTE: only visible when called from player | #### Precord API ##### Getting the list of precords ###### `GET /pvr/programmed/` *permission `pvr` (inferred)* Response `result`: Precord[] Example request: ```http GET /api/v{version}/pvr/programmed/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "has_record_gen": true, "channel_name": "France 2", "overlap_list": [ 195 ], "end": 1403755697, "media": "Disque dur", "path": "Enregistrements", "record_gen_id": 10, "enabled": true, "id": 190, "start": 1403755628, "broadcast_type": "tv", "subname": "", "state": "waiting_start_time", "channel_type": "", "name": "Test Repeat", "channel_quality": "auto", "conflict": true, "channel_uuid": "uuid-webtv-201", "error": "none", "altered": false }, { "has_record_gen": false, "channel_name": "France 2", "overlap_list": [], "end": 1403541511, "media": "NO NAME", "path": "Enregistrements", "record_gen_id": 0, "enabled": true, "id": 236, "start": 1403541361, "broadcast_type": "tv", "subname": "Sub Test", "state": "finished", "channel_type": "iptv", "name": "Test", "channel_quality": "auto", "conflict": false, "channel_uuid": "uuid-webtv-201", "error": "none", "altered": true } ] } ``` ##### Getting a specific precord ###### `GET /pvr/programmed/{id}` *permission `pvr` (inferred)* Returns the requested Precord | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: Precord Example request: ```http GET /api/v{version}/pvr/programmed/236 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "has_record_gen": false, "channel_name": "France 2", "overlap_list": [], "end": 1403541511, "media": "NO NAME", "path": "Enregistrements", "record_gen_id": 0, "enabled": true, "id": 236, "start": 1403541361, "broadcast_type": "tv", "subname": "Sub Test", "state": "finished", "channel_type": "iptv", "name": "Test", "channel_quality": "auto", "conflict": false, "channel_uuid": "uuid-webtv-201", "error": "none", "altered": true } } ``` ##### Updating a precord ###### `PUT /pvr/programmed/{id}` *permission `pvr` (inferred)* Update a Precord properties | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Request body (`application/json`): Precord Response `result`: Precord Example request: ```http PUT /api/v{version}/pvr/programmed/236 HTTP/1.1 Host: mafreebox.freebox.fr { "name": "test 2" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "has_record_gen": false, "channel_name": "France 2", "overlap_list": [], "end": 1403541511, "media": "NO NAME", "path": "Enregistrements", "record_gen_id": 0, "enabled": true, "id": 236, "start": 1403541361, "broadcast_type": "tv", "subname": "Sub Test", "state": "finished", "channel_type": "iptv", "name": "test 2", "channel_quality": "auto", "conflict": false, "channel_uuid": "uuid-webtv-201", "error": "none", "altered": true } } ``` ##### Delete a precord ###### `DELETE /pvr/programmed/{id}` *permission `pvr` (inferred)* Delete a Precord | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/pvr/programmed/236 HTTP/1.1 ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ##### Create a precord ###### `POST /pvr/programmed/` *permission `pvr` (inferred)* Create a new Precord Request body (`application/json`): Precord Response `result`: Precord \\ Example request\\: ```http POST /api/v{version}/pvr/programmed/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```text { "start": 1444240500, "end": 1444244100, "channel_uuid": "uuid-webtv-374", "name": "Secret Story", "subname: "La soirée des habitants" } ``` \\ Example response\\: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "id": 63, "media": "Disque dur", "path": "Enregistrements", "channel_uuid": "uuid-webtv-374", "channel_name": "NT1", "channel_type": "", "channel_quality": "auto", "broadcast_type": "tv", "start": 1444240500, "end": 1444244100, "name": "Secret Story", "subname": "La soirée des habitants", "state": "starting", "error": "none", "enabled": true, "altered": false, "conflict": false, "overlap_list": [], "margin_before": 0, "margin_after": 0, "has_record_gen": false, "record_gen_id": 0 } } ``` ### PVR Finished records Frecords (Finished records) are records that are finished or in progress. An Frecord object is created automatically when a Precord start time is reached. #### Frecord Frecord has the following attributes: ##### Object `Frecord` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | string | read-only | frecord id | | `media` | string | read-only | media name on which the record is written. See the Media API for more info. This property and can be empty when the file backing the record is not available, for example when secure is set. | | `path` | string | read-only | destination directory on the media storage | | `filename` | string | read-only | filename of the record | | `byte_size` | integer | read-only | size of the record file in bytes | | `has_record_gen` | boolean | read-only | if true, this frecord has been generated using a Generator | | `record_gen_id` | integer | read-only | if has_record_gen, this is the id of the generator | | `altered` | boolean | read-only | an frecord is altered when some part of the recording may be missing. This can be the case if a conflict occurred during the recording (or connection was down) | | `state` | string | read-only | Values: `disabled` (disabled), `start_error` (failed to start), `waiting_start_time` (scheduled), `starting` (starting), `running` (running), `running_error` (running with error), `failed` (failed), `finished` (finished). | | `error` | string | read-only | Values: `none`, `file_access_error`, `disk_full`, `private_but_no_private_dir`, `network_problem`, `resource_problem`, `no_stream_available`, `no_data_received`, `missed`, `stopped`, `internal_error`, `unknown_error`. | | `channel_uuid` | string | read-only | channel uuid | | `channel_name` | string | read-only | optional channel name | | `channel_quality` | string | read-only | Values: `auto`, `hd`, `sd`, `ld`, `3d`. | | `channel_type` | string | read-only | Values: `` (auto), `iptv` (use only iptv streams), `dvb` (use only dvb streams). | | `name` | string | | record name | | `subname` | string | | record subname | | `broadcast_type` | string | read-only | Values: `tv`, `radio`. | | `start` | integer | read-only | record start timestamp | | `end` | integer | read-only | record end timestamp | | `secure` | boolean | read-only | flag set when the record is protected by DRM | #### Frecord API ##### Getting the list of frecords ###### `GET /pvr/finished/` *permission `pvr` (inferred)* Response `result`: Frecord[] Example request: ```http GET /api/v{version}/pvr/finished/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "id": 5, "media": "Disque dur", "path": "Enregistrements", "filename": "M6 - Fier de ma maison - 27-06-2013 16h35 01h15 (5).m2ts", "byte_size": 4433869440, "has_record_gen": false, "record_gen_id": 0, "broadcast_type": "tv", "channel_uuid": "uuid-webtv-613", "channel_name": "M6", "channel_type": "dvb", "channel_quality": "hd", "name": "Fier de ma maison", "subname": "", "start": 1372343700, "end": 1372348200, "state": "finished", "error": "none", "enabled": true, "altered": true, "secure": false }, { "id": 22, "media": "", "path": "", "filename": "TF1 - Nos chers voisins - 17-09-2014 15h23 01h (22).m2ts", "byte_size": 2421095040, "has_record_gen": false, "record_gen_id": 0, "broadcast_type": "tv", "channel_uuid": "uuid-webtv-612", "channel_name": "TF1", "channel_type": "", "channel_quality": "auto", "name": "Nos chers voisins", "subname": "", "start": 1410960180, "end": 1410963780, "state": "finished", "error": "none", "enabled": true, "altered": true, "secure": true } ] } ``` ##### Getting a specific frecord ###### `GET /pvr/finished/{id}` *permission `pvr` (inferred)* Returns the requested Frecord | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: Frecord Example request: ```http GET /api/v{version}/pvr/finished/236 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "id": 236, "media": "NO NAME", "path": "", "filename": "France 3 - Tout le sport - 10-04-2015 20h00 10m (24).m2ts", "byte_size": 341752320, "has_record_gen": false, "record_gen_id": 0, "broadcast_type": "tv", "channel_uuid": "uuid-webtv-202", "channel_name": "France 3", "channel_type": "", "channel_quality": "auto", "name": "Tout le sport", "subname": "", "start": 1428688800, "end": 1428689400, "state": "finished", "error": "none", "enabled": true, "altered": true, "secure": false } } ``` ##### Updating an frecord ###### `PUT /pvr/finished/{id}` *permission `pvr` (inferred)* Update a Frecord properties | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Request body (`application/json`): Frecord Response `result`: Frecord Example request: ```http PUT /api/v{version}/pvr/finished/236 HTTP/1.1 Host: mafreebox.freebox.fr { "name": "Tout le sport", "subname": "On est les champions" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "id": 236, "media": "NO NAME", "path": "", "filename": "France 3 - Tout le sport - 10-04-2015 20h00 10m (24).m2ts", "byte_size": 341752320, "has_record_gen": false, "record_gen_id": 0, "broadcast_type": "tv", "channel_uuid": "uuid-webtv-202", "channel_name": "France 3", "channel_type": "", "channel_quality": "auto", "name": "Tout le sport", "subname": "On est les champions", "start": 1428688800, "end": 1428689400, "state": "finished", "error": "none", "enabled": true, "altered": true, "secure": false } } ``` ##### Delete an frecord ###### `DELETE /pvr/finished/{id}` *permission `pvr` (inferred)* Delete a Frecord and associated files | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http DELETE /api/v{version}/pvr/finished/236 HTTP/1.1 ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` ### Storage media Media objects represent a storage on which records can be written to, typically a disk. #### Media Media has the following attributes: ##### Object `Media` | Property | Type | Access | Description | | --- | --- | --- | --- | | `media` | string | read-only | name of the storage medium | | `free_bytes` | integer | read-only | number of free bytes on the medium | | `total bytes int [ro]` | any | | total number of bytes on the medium | | `record_time` | integer | read-only | estimated record time in seconds for multiple channel types and qualities | #### Media API ##### Getting the list of media ###### `GET /pvr/media/` *permission `pvr` (inferred)* Response `result`: { media: string, free_bytes: integer, total_bytes: integer, record_time: { dvb: { sd: integer, hd: integer, 3d: integer }, iptv: { ld: integer, sd: integer, hd: integer, 3d: integer } } }[] Example request: ```http GET /api/v{version}/pvr/media/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "media": "Disque dur", "free_bytes": 39700000000, "total_bytes": 244950000000, "record_time": { "dvb": { "sd": 48461, "hd": 35245, "3d": 35245 }, "iptv": { "ld": 155078, "sd": 110770, "hd": 51012, "3d": 51012 } } }, { "media": "NO NAME", "free_bytes": 873930000, "total_bytes": 7790000000, "record_time": { "dvb": { "sd": 1066, "hd": 775, "3d": 775 }, "iptv": { "ld": 3413, "sd": 2438, "hd": 1122, "3d": 1122 } } } ] } ``` ## RRD ### RRD [UNSTABLE] With the rrd API you can retrieve stats collected on the Freebox. Right now the stats available are: network stats, switch stats, dsl stats, and temperature stats. #### RRD Fetch Object This is the object used to get stats ##### Object `RRDFetch` | Property | Type | Access | Description | | --- | --- | --- | --- | | `db` | string | | Name of the rrd database to read. It can take one of the following values Values: `net` (network stats), `temp` (temperature stats), `dsl` (xDSL stats), `switch` (switch stats). | | `date_start` | integer | | The requested start timestamp of the stats to get NOTE: this can be adjusted to fit the best available resolution | | `date_end` | integer | | The requested end timestamp of the stats to get NOTE: this can be adjusted to fit the best available resolution | | `precision` | integer | | By default all values are cast to int, if you need floating point precision you can provide a precision factor that will be applied to all values before being returned. For instance if you want 2 digit precision you should use a precision of 100, and divide the obtained results by 100. | | `fields` | string[] | | If you are only interested in getting some fields you can provide the list of fields you want to get. | For the net database the fields are: | Field | Description | | --- | --- | | bw_up | upload available bandwidth (in byte/s) | | bw_down | download available bandwidth (in byte/s) | | rate_up | upload rate (in byte/s) | | rate_down | download rate (in byte/s) | | vpn_rate_up | vpn client upload rate (in byte/s) | | vpn_rate_down | vpn client download rate (in byte/s) | For the temp database the fields are: | Field | Description | | --- | --- | | cpum | temperature cpum (in °C) | | cpub | temperature cpub (in °C) | | sw | temperature sw (in °C) | | hdd | temperature hdd (in °C) | | fan_speed | fan rpm | | temp1 | temperature sensor 1 (in °C) [DEPRECATED, use cpum] | | temp2 | temperature sensor 2 (in °C) [DEPRECATED, use cpub] | | temp3 | temperature sensor 3 (in °C) [DEPRECATED, use sw] | For the dsl database the fields are: | Field | Description | | --- | --- | | rate_up | dsl available upload bandwidth (in byte/s) | | rate_down | dsl available download bandwidth (in byte/s) | | snr_up | dsl upload signal/noise ratio (in 1/10 dB) | | snr_down | dsl download signal/noise ratio (in 1/10 dB) | For the switch database the fields are: | Field | Description | | --- | --- | | rx_1 | receive rate on port 1 (in byte/s) | | tx_1 | transmit on port 1 (in byte/s) | | rx_2 | receive rate on port 2 (in byte/s) | | tx_2 | transmit on port 2 (in byte/s) | | rx_3 | receive rate on port 3 (in byte/s) | | tx_3 | transmit on port 3 (in byte/s) | | rx_4 | receive rate on port 4 (in byte/s) | | tx_4 | transmit on port 4 (in byte/s) | #### Get RRD stats [UNSTABLE] ##### `POST /rrd/` *permission `settings` · unstable* Request body (`application/json`): RRDFetch Response `result`: { date_start: integer (unix-time), date_end: integer (unix-time), data: { time: integer (unix-time), [key: string]: number }[] } Example request: ```http POST /api/v{version}/rrd/ HTTP/1.1 Host: mafreebox.freebox.fr { "db": "temp", "fields": [ "temp1" ], "precision": 10 } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "date_start": 1353048060, "data": [ { "temp1": 540, "time": 1353060840 }, { "temp1": 545, "time": 1353060900 }, { "temp1": 540, "time": 1353069600 } ], "date_end": 1353069660 } } ``` ##### `GET /rrd/` *unstable* Same as post request, but allowed without ‘settings’ permission **Correction:** Query string, not body; fields is ignored. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `db` | query | string | Name of the rrd database to read. It can take one of the following values Values: `net` (network stats), `temp` (temperature stats), `dsl` (xDSL stats), `switch` (switch stats). | | `date_start` (optional) | query | integer | The requested start timestamp of the stats to get NOTE: this can be adjusted to fit the best available resolution | | `date_end` (optional) | query | integer | The requested end timestamp of the stats to get NOTE: this can be adjusted to fit the best available resolution | | `precision` (optional) | query | integer | By default all values are cast to int, if you need floating point precision you can provide a precision factor that will be applied to all values before being returned. For instance if you want 2 digit precision you should use a precision of 100, and divide the obtained results by 100. | Response `result`: { date_start: integer (unix-time), date_end: integer (unix-time), data: { time: integer (unix-time), [key: string]: number }[] } ## Standby ### Standby The Standby API allows you to configure Wi-Fi schedule. On boxes that have has_standby set to true in their `SystemConfig` information, it is possible to configure box standby and wake-up. #### Standby Errors When attempting to access this API, you may encounter the following errors: | error_code | Description | | --- | --- | | inval | invalid parameters | #### Standby config object Standby config object have the following properties: ##### Object `StandbyConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `use_planning` | boolean | | is the planning enabled | | `planning_mode` | string | | current planning mode Values: `wifi_off` (Wi-Fi disabled), `standby` (Freebox standby). | | `resolution` | integer | read-only | planning resolution (number of slots per day) | | `mapping` | boolean[] | | mapping for planning : true or false mapping[0] is monday at 0:0 mapping[7 * resolution - 1] is sunday last slot (each slot has a duration of 60 * 24 / resolution minutes) The boolean value indicates whether the planning is in effect (i.e: Wi-Fi disabled, or box standing by) | #### Standby status object Standby status object have the following properties: ##### Object `StandbyStatus` | Property | Type | Access | Description | | --- | --- | --- | --- | | `use_planning` | boolean | read-only | is the planning enabled | | `planning_mode` | string | read-only | Type of planning that is configured, just like in StandbyConfig | | `next_change` | integer (unix-time) | read-only | UNIX timestamp (seconds) timestamp of the scheduled next change, according to planning | | `available_planning_modes` | any[] | read-only | array of available planning modes. Individual array elements are enum values just like planning_mode in StandbyConfig | #### Standby API ##### Get standby status ###### `GET /standby/status` Returns the Standby status object Response `result`: StandbyStatus Example request: ```http GET /api/v{version}/standby/status HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "use_planning": true, "planning_mode": "standby", "next_change": 1651135474996, "available_planning_modes": [ "wifi_off", "standby" ] } } ``` ##### Get standby config Get the `StandbyConfig` **Example request**: ```http GET /api/v{version}/standby/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` **Example response**: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "use_planning": false, "planning_mode": "suspend", "mapping": [ false, false, false, false, false, false, false, false ], "resolution": 48 } } ``` ##### Update standby config ###### `PUT /standby/config` *permission `settings` (inferred)* Request body (`application/json`): StandbyConfig Response `result`: StandbyConfig Example request: ```http PUT /api/v{version}/standby/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "use_planning": true, "planning_mode": "suspend", "mapping": [ false, false, false, false, false, false, false, false ], "resolution": 48 } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "use_planning": false, "planning_mode": "suspend", "mapping": [ false, false, false, false, false, false, false, false, false ], "resolution": 48 } } ``` ## Storage ### Storage API [UNSTABLE] This API allows you to manage the Freebox internal disk and disks connected to the Freebox This API is unstable, it can be modified without notice in next releases. #### Storage API Errors When attempting to access this API, you may encounter the following errors: | error_code | Description | | --- | --- | | not_found | No disk/partition with this id | | invalid_disk | No such disk | | is_a_partition | This is not a disk but a partition | | is_internal | This action is not permitted on internal disk | | op_not_supported | Operation not supported | | op_failed | Operation failed | | disk_busy | Disk is busy | | partition_not_found | Partition not found | | partition_needed | Partition needed | #### Disk Partition object Operation progress has the following attributes: ##### Object `OperationProgress` | Property | Type | Access | Description | | --- | --- | --- | --- | | `done_steps` | integer | read-only | number of steps done | | `max_steps` | integer | read-only | total number of steps | | `percent` | integer | read-only | current step progress | Disk partitions have the following attributes: ##### Object `DiskPartition` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | read-only | unique partition id | | `disk_id` | integer | read-only | related disk id | | `state` | string | | Values: `error` (Partition has error), `checking` (Partition check in progress), `formatting` (Partition format in progress), `mounting` (Partition mount in progress), `maintenance` (Partition is in maintenance mode), `mounted` (Partition is ready), `umounting` (Partition umount in progress), `umounted` (Partition is umounted), `ejecting` (Partition ejection in progress). | | `fstype` | string | read-only | Values: `empty`, `unknown`, `xfs`, `ext4`, `vfat`, `ntfs`, `hf`, `hfsplus`, `swap`, `exfat`. | | `label` | string | | partition name | | `path` | string | read-only | partition mount point (encoded in base64 as explained in fs API) | | `total_bytes` | integer | read-only | partition size (in bytes) | | `used_bytes` | integer | read-only | partition used space (in bytes) | | `free_bytes` | integer | read-only | partition free space (in bytes) | | `fsck_result` | string | read-only | fsck result Values: `no_run_yet` (Partition has not been checked yet), `running` (Check is in progress), `fs_clean` (File system is ok), `fs_corrected` (File system was corrected), `fs_needs_correction` (File system need correction), `failed` (File system has unrecoverable error). | | `operation_pct` | OperationProgress | read-only | partition operation progress | #### Storage Disk object Storage disks have the following attributes: ##### Object `StorageDisk` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | read-only | the disk id | | `type` | string | read-only | Values: `internal` (Freebox internal disk), `usb` (usb disk), `sata` (sata disk), `nvme` (nvme disk). | | `state` | string | | Values: `error` (Disk has error), `disabled` (Disk is disabled), `enabled` (Disk is enabled), `formatting` (Disk is formatting). | | `connector` | integer | read-only | Disk physical connector id | | `total_bytes` | integer | read-only | Disk size (in bytes) | | `table_type` | integer | read-only | Documented values: `msdos`, `gpt`, `superfloppy`, `empty`. | | `model` | string | read-only | Disk model | | `serial` | string | read-only | Disk serial number | | `firmware` | string | read-only | Disk firmware version | | `temp` | integer | read-only | Disk temperature (when supported) in °C | | `operation_pct` | OperationProgress | read-only | partition operation progress | | `partitions` | DiskPartition[] | read-only | list of disk partitions | | `idle` | boolean | read-only | is disk idle (when available) | | `idle_duration` | integer | read-only | disk idle duration (in seconds) (when available) | | `spinning` | boolean | read-only | is disk spinning (when available) | | `active_duration` | integer | read-only | disk activity duration (in seconds) (when available) | | `time_before_spindown` | integer | read-only | seconds left before disk spin down (in seconds) (when available) | | `read_requests` | integer | read-only | Number of read requests sent since to disk since boot (when available) | | `read_error_requests` | integer | read-only | Number of read requests in error since boot. Might indicate disk failure (when available) | | `write_requests` | integer | read-only | Number of write requests sent since to disk since boot (when available) | | `write_error_requests` | integer | read-only | Number of write requests in error since boot. Might indicate disk failure (when available) | #### Storage Disk API ##### Get the list of disks ###### `GET /storage/disk/` *unstable* Returns the collection of all StorageDisk Response `result`: StorageDisk[] Example request: ```http GET /api/v{version}/storage/disk/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "idle_duration": 368, "spinning": true, "table_type": "msdos", "firmware": "PB2ICC0E", "type": "internal", "idle": true, "connector": 0, "id": 1, "state": "enabled", "time_before_spindown": 232, "total_bytes": 250059350016, "model": "Hitachi HCC545025B9A300", "active_duration": 0, "temp": 51, "serial": "GSCH35VC", "partitions": [ { "fstype": "ext4", "total_bytes": 245091500032, "label": "Disque dur", "id": 3, "fsck_result": "no_run_yet", "state": "mounted", "disk_id": 1, "free_bytes": 68120969216, "used_bytes": 164520534016, "path": "L0Rpc3F1ZSBkdXI=" } ] }, { "type": "usb", "total_bytes": 125435904, "connector": 1, "id": 1001, "active_duration": 0, "partitions": [ { "fstype": "ext4", "total_bytes": 121418752, "label": "Disque 1", "id": 1002, "fsck_result": "no_run_yet", "state": "mounted", "disk_id": 1001, "free_bytes": 108904448, "used_bytes": 6245376, "path": "L0Rpc3F1ZSAx" } ], "idle_duration": 0, "state": "enabled", "idle": false, "spinning": false, "model": "", "table_type": "gpt", "temp": 0, "serial": "", "firmware": "" } ] } ``` ##### Get a given disk info ###### `GET /storage/disk/{id}` *unstable* Returns the StorageDisk with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: StorageDisk Example request: ```http GET /api/v{version}/storage/disk/1 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "idle_duration": 464, "spinning": true, "table_type": "msdos", "firmware": "PB2ICC0E", "type": "internal", "idle": true, "connector": 0, "id": 1, "state": "enabled", "time_before_spindown": 136, "total_bytes": 250059350016, "model": "Hitachi HCC545025B9A300", "active_duration": 0, "temp": 51, "serial": "GSCH35VC", "partitions": [ { "fstype": "ext4", "total_bytes": 245091500032, "label": "Disque dur", "id": 3, "fsck_result": "no_run_yet", "state": "mounted", "disk_id": 1, "free_bytes": 68120969216, "used_bytes": 164520534016, "path": "L0Rpc3F1ZSBkdXI=" } ] } } ``` ##### Update a disk state ###### `PUT /storage/disk/{id}` *permission `settings` (inferred) · unstable* Enable/Disable a disk | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Request body (`application/json`): { state: string } Response `result`: StorageDisk Example request: ```http PUT /api/v{version}/storage/disk/1 HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "state": "disabled" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "type": "usb", "total_bytes": 125435904, "connector": 1, "id": 1001, "active_duration": 0, "partitions": [ { "fstype": "ext4", "total_bytes": 121418752, "label": "Disque 1", "id": 1002, "fsck_result": "no_run_yet", "state": "umounted", "disk_id": 1001, "free_bytes": 108904448, "used_bytes": 6245376, "path": "L0Rpc3F1ZSAx" } ], "idle_duration": 0, "state": "disabled", "idle": false, "spinning": false, "model": "", "table_type": "gpt", "temp": 0, "serial": "", "firmware": "" } } ``` ##### Get FS advices ###### `GET /storage/disk/{disk_id}/fsadvice` *unstable* Check disk FS and get formatting advices. To be able to get FS advice for a disk you need to provide the disk_id. Specify dedicated_disk for a disk that will only be used with the Freebox server (no need to specify it for a SATA internal disk). If the disk is empty do not specify partition_id in order to get advice for creating a new one. If the disk contains a partition specify the partition_id that needs to be checked. Reasons can be one of the following: | Parameter | In | Type | Description | | --- | --- | --- | --- | | `disk_id` | path | integer | | | `partition_id` (optional) | query | string | | | `dedicated_disk` (optional) | query | string | | Response `result`: { fstype: string, table_type: string, reason: string, partitions_to_delete: { fstype: string, total_bytes: integer, label: string, id: integer, internal: boolean, fsck_result: string, state: string, disk_id: integer, free_bytes: integer, used_bytes: integer, path: string }[] } Example request: ```http GET /api/v{version}/storage/disk/1000/fsadvice?partition_id=1003&dedicated_disk=false HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "fstype": "exfat", "table_type": "gpt", "reason": "max_file_size", "partitions_to_delete": [ { "fstype": "exfat", "total_bytes": 1000000000000, "label": "EFI", "id": 1001, "internal": false, "fsck_result": "no_run_yet", "state": "mounted", "disk_id": 1000, "free_bytes": 1000000000000, "used_bytes": 1310000, "path": "L0Rpc3F1ZSAxIDE=" }, { "fstype": "exfat", "total_bytes": 1000000000000, "label": "DATA", "id": 1002, "internal": false, "fsck_result": "no_run_yet", "state": "mounted", "disk_id": 1000, "free_bytes": 1000000000000, "used_bytes": 1310000, "path": "L1ZvbHVtZSAxMDAwR28=" } ] } } ``` | Reason | Description | | --- | --- | | max_file_size | Performance and bigger that 4GB files support | | perf_and_compat | Performance and device compatibility | | sata_performance | Performance for SATA disk | | nvme_performance | Performance for NVMe disk | | no_partition | Missing partition id on already formatted disk | | partition_error | Partition is in error state | ##### Format a disk ###### `PUT /storage/disk/{id}/format/` *permission `settings` (inferred) · unstable* Format the disk with the given id To be able to format a disk you need to provide the following parameters (JSON encoded). There will be one partition using all the available space on disk. All previous data will be lost. This parameters will be ignored if you format the Freebox internal disk NOTE: once started you can monitor the format process getting the disk information (see StorageDisk operation_pct field) | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Request body (`application/json`): { table_type: string, fs_type: string, label: string } Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http PUT /api/v{version}/storage/disk/1001/format HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "label": "freebox", "fs_type": "vfat", "table_type": "msdos" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` #### Storage Partition API ##### Get the list of partitions ###### `GET /storage/partition/` *unstable* Returns the collection of all DiskPartition Response `result`: DiskPartition[] Example request: ```http GET /api/v{version}/storage/partition/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "fstype": "ext4", "total_bytes": 245091500032, "label": "Disque dur", "id": 3, "fsck_result": "no_run_yet", "state": "umounted", "disk_id": 1, "free_bytes": 68120969216, "used_bytes": 164520534016, "path": "L0Rpc3F1ZSBkdXI=" }, { "fstype": "vfat", "total_bytes": 123485184, "label": "freebox", "id": 1002, "fsck_result": "no_run_yet", "state": "mounted", "disk_id": 1001, "free_bytes": 123484672, "used_bytes": 512, "path": "L2ZyZWVib3g=" } ] } ``` ##### Get a given partition info ###### `GET /storage/partition/{id}` *unstable* Returns the DiskPartition with the given id | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: DiskPartition Example request: ```http GET /api/v{version}/storage/partition/1002 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "fstype": "vfat", "total_bytes": 123485184, "label": "freebox", "id": 1002, "fsck_result": "no_run_yet", "state": "mounted", "disk_id": 1001, "free_bytes": 123484672, "used_bytes": 512, "path": "L2ZyZWVib3g=" } } ``` ##### Update a partition state ###### `PUT /storage/partition/{id}` *permission `settings` (inferred) · unstable* Enable/Disable a partition | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Request body (`application/json`): { state: string } Response `result`: DiskPartition Example request: ```http PUT /api/v{version}/storage/partition/1 HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "state": "umounted" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "fstype": "vfat", "total_bytes": 123485184, "label": "freebox", "id": 1002, "fsck_result": "no_run_yet", "state": "umounted", "disk_id": 1001, "free_bytes": 123484672, "used_bytes": 512, "path": "L2ZyZWVib3g=" } } ``` ##### Check a partition ###### `PUT /storage/partition/{id}/check/` *permission `settings` (inferred) · unstable* Checks the partition with the given id To be able to check a partition you need to provide the following parameters (JSON encoded): NOTE: once started you can monitor the fsck process getting the partition information (see DiskPartition operation_pct field) | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Request body (`application/json`): { checkmode: string } Response: no result schema documented (envelope `{ "success": true }`). Example request: ```http PUT /api/v{version}/storage/partition/1002/check HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "checkmode": "ro" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true } ``` #### Storage Config StorageConfig has the following attributes: ##### Object `StorageConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `external_pm_enabled` | boolean | | enable/disable external disk power management | | `external_pm_idle_before_spindown` | integer | | idle time in minutes to wait before spinning down an external disk | #### Storage config API ##### Get the current storage configuration ###### `GET /storage/config/` *unstable* Get the StorageConfig Response `result`: StorageConfig Example request: ```http GET /api/v{version}/storage/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "external_pm_idle_before_spindown": 10, "external_pm_enabled": true } } ``` ##### Update the External Storage configuration ###### `PUT /storage/config/` *permission `settings` (inferred) · unstable* Update the StorageConfig Request body (`application/json`): StorageConfig Response `result`: StorageConfig Example request: ```http PUT /api/v{version}/storage/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "external_pm_enabled": false } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "external_pm_idle_before_spindown": 10, "external_pm_enabled": false } } ``` ### RAID API [UNSTABLE] This API allows you to manage the Freebox internal raid arrays for disks connected to the Freebox This API is unstable, it can be modified without notice in next releases. #### RAID API Errors When attempting to access this API, you may encounter the following errors: | error_code | Description | | --- | --- | | inval | Invalid parameters(s) | | no_sys | Function not available | | member_not_found | No member found | | members_too_many | Too many members | | array_not_found | RAID array not found | | array_stop_failed | Error when stopping the RAID array | | array_start_failed | Error when starting the RAID array | | array_destroy_failed | Error when destroying the RAID array | | array_not_running | The RAID array is not active | | array_not_stopped | The RAID array is not stopped | | array_degraded | The RAID array is degraded | | array_not_degraded | The RAID array is not degraded | | array_complete | The RAID array is full | | already_member | The specified disks are already members of a RAID array | | disk_more_than_once | The same disk has been specified more than once | | disks_missing | Insufficient number of disks | | bad_disk_location | Only internal drives can be used in a RAID array | | disk_internal | This disk cannot be used in a RAID array | | disk_busy | Disk is busy | | create_failed | RAID array creation failed | | create_too_many_members | The number of disks is too high (basic) | | create_not_enough_members | The number of disks is too small | | create_bad_member_count | The number of disks is incorrect (raid10) | | sync_action_bad_level | This type of RAID array does not support synchronization | | sync_action_array_busy | This RAID array is being resynchronized/restored | | sync_action_bad_action | It is not possible to force resynchronization manually | | sync_action_failed | This action has been denied | | check_interval_too_large | Check interval is too long | | check_interval_not_supported | This check interval is not supported | | remove_bad_level | This type of RAID array does not allow member removal | | remove_not_enough_active | Not enough active members to allow removal of a member | | remove_failed | Failure to remove a member | | add_too_many | Too many new members | | add_member_too_small | One of the members is too small to be added to this array | | add_failed | Failed to add member | | member_examine_data_failed | Unable to examine member data | | sync_speed_min_greaterthan_max | Minimum sync speed is more important than maximum speed | | sync_speed_min_toohigh | The minimum sync speed is too high | | sync_speed_max_toohigh | The maximum sync speed it too high | | sync_speed_min_toolow | The minimum sync speed is too low | | sync_speed_max_toolow | The maximum sync speed is too low | | sync_speed_set_failed | Error changing synchronization speed | | grow_bad_level | RAID level migration not possible | | grow_not_enough_disks | Not enough disks for expansion | | grow_failed | Expansion failed | | grow_array_busy | Cannot extend a busy RAID array | | grow_member_too_small | One of the members is too small to expand the raid array | | rescan_member_failed | One or more members could not be rescanned | | add_spares_busy | Cannot add out-of-sync disks when the array is busy | | add_spares_nospares | No out-of-sync member detected | | add_spares_complete | The RAID Array is full and cannot add an out of sync member | | add_spares_failed | Failed to add out-of-sync disks | #### RAID API objects ##### RAID Array object ###### Object `RaidArray` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | read-only | unique id of this array. Used as a reference for API calls. | | `state` | string | | Values: `stopped` (Array is stopped), `running` (Array is running), `error` (Array is in error). | | `name` | string | | The array name | | `level` | string | | Values: `basic` (Basic RAID level, like a single drive raid1 array), `raid0` (RAID 0), `raid1` (RAID 1), `raid5` (RAID 5), `raid10` (RAID 10). | | `disk_id` | integer | read-only | The disk id of the array, for use with the disk format API. | | `uuid` | string | read-only | The array unique id. Only this id is guaranteed to stay stable across reboots. | | `sync_action` | string | read-only | Values: `idle` (Array is idle), `resync` (Sync operation in progress), `recover` (Recover operation in progress), `check` (Array is being checked), `repair` (Repair operation in progress), `reshape` (Array growth in progress), `frozen` (Array is frozen). | | `sysfs_state` | string | read-only | Low-level Linux-specific md state value read in sysfs array_state property. Values: `clear`, `inactive`, `suspended`, `readonly`, `read_auto`, `clean`, `active`, `write_pending`, `active_idle`. | | `array_size` | integer | read-only | Size of array in bytes. | | `raid_disks` | integer | read-only | Number of members that should be in this array. | | `sync_speed` | integer | read-only | Sync speed in bytes per second | | `sync_completed_pos` | integer | read-only | Current position of sync process. | | `sync_completed_end` | integer | read-only | End position of sync process: total of bytes to sync. | | `sync_completed_percent` | integer | read-only | Percentage of sync completion. | | `check_interval` | integer | read-only | Check interval in seconds. | | `last_check` | integer | read-only | Unix timestamp of last check in seconds. | | `next_check` | integer | read-only | Unix timestamp of next check in seconds. Might be 0 if check_interval is 0. | | `degraded` | boolean | read-only | Whether the array is degraded or not. | | `members` | RaidMember[] | | List of members of this array | ##### RAID Member object ###### Object `RaidMember` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | read-only | unique id of this member. This corresponds to the disk id, usable with the Storage Disk API. | | `array_id` | integer | read-only | id of the array this member is in | | `role` | string | read-only | Values: `active` (Active member of the array), `faulty` (Faulty member), `spare` (Member kept as spare), `missing` (Missing (removed or dead) member of the array). | | `set_name` | string | read-only | name of the array this member is into | | `set_uuid` | string | read-only | uuid of the array this member is into | | `dev_uuid` | string | read-only | uuid of this member | | `device_location` | string | read-only | internal location of this member. Possible slot values: sata-internal-p0, sata-internal-p1, sata-internal-p2, sata-internal-p4 | | `total_bytes` | integer | read-only | size of this member in bytes | | `active_device` | integer | read-only | device number inside the array | | `corrected_read_errors` | integer | read-only | Device read errors count | | `sct_erc_supported` | boolean | read-only | Whether SCT_ERC is supported by the device according to its S.M.A.R.T. data. | | `sct_erc_enabled` | boolean | read-only | Whether SCT_ERC is enabled on the device according to its S.M.A.R.T. data. | | `disk` | RaidDisk | read-only | A few properties of the disk. | ##### RAID Disk object ###### Object `RaidDisk` | Property | Type | Access | Description | | --- | --- | --- | --- | | `model` | string | read-only | Disk model. | | `serial` | string | read-only | Disk serial number. | | `firmware` | string | read-only | Disk firmware revision | | `temp` | integer | read-only | Disk temperature in °C. | #### RAID API actions ##### Get the list of RAID arrays ###### `GET /storage/raid/` *unstable* Returns the collection of all RaidArray Response `result`: RaidArray[] Example request: ```http GET /api/v{version}/storage/raid/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": [ { "degraded": false, "raid_disks": 4, "next_check": 0, "sync_action": "idle", "level": "raid5", "uuid": "a4f1fbf3-f8e7-453f-19ec-842d6f4e2895", "sysfs_state": "clear", "id": 0, "sync_completed_pos": 0, "members": [ { "total_bytes": 1000000000000, "active_device": 0, "id": 1000, "corrected_read_errors": 0, "array_id": 0, "disk": { "firmware": "02.01A02", "temp": 43, "serial": "WD-WX91A42F69NE", "model": "WDC WD10JUCX-56WPNY0" }, "role": "active", "sct_erc_supported": false, "sct_erc_enabled": false, "dev_uuid": "666793c9-2d04-9d9e-5c8a-2f13eb7f2e9e", "device_location": "sata-internal-p1", "set_name": "Freebox", "set_uuid": "a4f1fbf3-f8e7-453f-19ec-842d6f4e2895" }, { "total_bytes": 1000000000000, "active_device": 1, "id": 2000, "corrected_read_errors": 0, "array_id": 0, "disk": { "firmware": "02.01A02", "temp": 47, "serial": "WD-WX91A42F1337", "model": "WDC WD10JUCX-56WPNY0" }, "role": "active", "sct_erc_supported": false, "sct_erc_enabled": false, "dev_uuid": "231b35d0-c37f-9d3c-be7a-b7b8485341ce", "device_location": "sata-internal-p0", "set_name": "Freebox", "set_uuid": "a4f1fbf3-f8e7-453f-19ec-842d6f4e2895" }, { "total_bytes": 1000000000000, "active_device": 2, "id": 3000, "corrected_read_errors": 0, "array_id": 0, "disk": { "firmware": "02.01A02", "temp": 46, "serial": "WD-WX91A42FZ3I9", "model": "WDC WD10JUCX-56WPNY0" }, "role": "active", "sct_erc_supported": false, "sct_erc_enabled": false, "dev_uuid": "d28e5fd8-5e2a-baf3-fd24-6fe5ff2593d6", "device_location": "sata-internal-p2", "set_name": "Freebox", "set_uuid": "a4f1fbf3-f8e7-453f-19ec-842d6f4e2895" }, { "total_bytes": 1000000000000, "active_device": 3, "id": 4000, "corrected_read_errors": 0, "array_id": 0, "disk": { "firmware": "02.01A02", "temp": 46, "serial": "WD-WX91A42F1333", "model": "WDC WD10JUCX-56WPNY0" }, "role": "active", "sct_erc_supported": false, "sct_erc_enabled": false, "dev_uuid": "fdf5a84a-c427-e1ef-aa12-1732d2cf689f", "device_location": "sata-internal-p3", "set_name": "Freebox", "set_uuid": "a4f1fbf3-f8e7-453f-19ec-842d6f4e2895" } ], "array_size": 3000000000000, "state": "running", "sync_speed": 0, "name": "Freebox", "check_interval": 0, "disk_id": 6000, "last_check": 1576082428, "sync_completed_end": 0, "sync_completed_percent": 0 } ] } ``` ##### Get a given RAID array info ###### `GET /storage/raid/{id}` *unstable* Returns a single RaidArray | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | integer | | Response `result`: RaidArray Example request: ```http GET /api/v{version}/storage/raid/0 HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "degraded": false, "raid_disks": 4, "next_check": 0, "sync_action": "idle", "level": "raid5", "uuid": "a4f1fbf3-f8e7-453f-19ec-842d6f4e2895", "sysfs_state": "clear", "id": 0, "sync_completed_pos": 0, "members": [ { "total_bytes": 1000000000000, "active_device": 0, "id": 1000, "corrected_read_errors": 0, "array_id": 0, "disk": { "firmware": "02.01A02", "temp": 43, "serial": "WD-WX91A42F69NE", "model": "WDC WD10JUCX-56WPNY0" }, "role": "active", "sct_erc_supported": false, "sct_erc_enabled": false, "dev_uuid": "666793c9-2d04-9d9e-5c8a-2f13eb7f2e9e", "device_location": "sata-internal-p1", "set_name": "Freebox", "set_uuid": "a4f1fbf3-f8e7-453f-19ec-842d6f4e2895" }, { "total_bytes": 1000000000000, "active_device": 1, "id": 2000, "corrected_read_errors": 0, "array_id": 0, "disk": { "firmware": "02.01A02", "temp": 47, "serial": "WD-WX91A42F1337", "model": "WDC WD10JUCX-56WPNY0" }, "role": "active", "sct_erc_supported": false, "sct_erc_enabled": false, "dev_uuid": "231b35d0-c37f-9d3c-be7a-b7b8485341ce", "device_location": "sata-internal-p0", "set_name": "Freebox", "set_uuid": "a4f1fbf3-f8e7-453f-19ec-842d6f4e2895" }, { "total_bytes": 1000000000000, "active_device": 2, "id": 3000, "corrected_read_errors": 0, "array_id": 0, "disk": { "firmware": "02.01A02", "temp": 46, "serial": "WD-WX91A42FZ3I9", "model": "WDC WD10JUCX-56WPNY0" }, "role": "active", "sct_erc_supported": false, "sct_erc_enabled": false, "dev_uuid": "d28e5fd8-5e2a-baf3-fd24-6fe5ff2593d6", "device_location": "sata-internal-p2", "set_name": "Freebox", "set_uuid": "a4f1fbf3-f8e7-453f-19ec-842d6f4e2895" }, { "total_bytes": 1000000000000, "active_device": 3, "id": 4000, "corrected_read_errors": 0, "array_id": 0, "disk": { "firmware": "02.01A02", "temp": 46, "serial": "WD-WX91A42F1333", "model": "WDC WD10JUCX-56WPNY0" }, "role": "active", "sct_erc_supported": false, "sct_erc_enabled": false, "dev_uuid": "fdf5a84a-c427-e1ef-aa12-1732d2cf689f", "device_location": "sata-internal-p3", "set_name": "Freebox", "set_uuid": "a4f1fbf3-f8e7-453f-19ec-842d6f4e2895" } ], "array_size": 3000000000000, "state": "running", "sync_speed": 0, "name": "Freebox", "check_interval": 0, "disk_id": 6000, "last_check": 1576082428, "sync_completed_end": 0, "sync_completed_percent": 0 } } ``` ##### Create a RAID array ###### `POST /storage/raid/` *permission `settings` (inferred) · unstable* Response: no result schema documented (envelope `{ "success": true }`). ##### Delete a RAID array ###### `DELETE /storage/raid/{id}` *permission `settings` (inferred) · unstable* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). ##### Start or stop a RAID array Send a `RaidArray` with properties “id” and “state”. This is used to start and stop an array by changing the state to “stopped” or “running”. These are the only two supported operations. Any change to other fields is ignored. ###### `PUT /storage/raid/{id}` *permission `settings` (inferred) · unstable* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). ##### Force start a RAID array In case an array is incomplete, but has enough data to start in degraded mode, it won’t start automatically at boot, and the force start can be used. Can only be done if array state is “error”. ###### `POST /storage/raid/{id}/forcestart` *permission `settings` (inferred) · unstable* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). ##### Remove faulty members from RAID array In case an array has faulty members, it might be desirable to delete them to add others members instead. Can only be done if array is not running. ###### `DELETE /storage/raid/{id}/members/faulty` *permission `settings` (inferred) · unstable* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). ##### Add members to an existing array that has missing members In case an array is incomplete (has missing members), either because they were removed physically, or after becoming faulty, it’s possible to add new members to let the reconstruction happen. Can only be done if array is not running. ###### `PUT /storage/raid/{id}/members` *permission `settings` (inferred) · unstable* Send a json object containing a “members” property, which is array of RaidMember objects. Only the “id” property of each member is required. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response `result`: RaidMember Send a json object containing a “members” property, which is array of `RaidMember` objects. Only the “id” property of each member is required. ##### Re-add out-of-sync members that appear as spares In case an array has been force-started without a member, and then said member is physically plugged, it won’t be added automatically and will appear with the “spare” role, this operation must be used. Can only be done if the array has a member with the “spare” role, and is not running. ###### `POST /storage/raid/{id}/members/addspares` *permission `settings` (inferred) · unstable* | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). ## SFP ### SFP On boxes that have has_lan_sfp set to true in their `SystemConfig` information, it is possible to configure the LAN SFP port. #### SFP Errors When attempting to access this API, you may encounter the following errors: | error_code | Description | | --- | --- | | inval | invalid parameters | | noent | invalid id | | internal | system internal error | #### SFP config object SFP config object has the following properties: ##### Object `SfpConfig` | Property | Type | Access | Description | | --- | --- | --- | --- | | `sfp_type_forced` | boolean | | Indicate whether the SFP type is forced | | `sfp_type_forced_value` | string | | What SFP type is forced (valid only when sfp_type_forced is true). Valid values are provided in available_sfp_types | | `available_sfp_types` | string[] | read-only | array containing what SFP types can be configured on the LAN SFP port. Possible values are listed in the following table: Item values: `p2p_1g` (1000BASE-X), `p2p_2d5g_no_aneg` (2500BASE-X), `p2p_10g` (10GBASE-R), `copper_1g` (1000BASE-T), `copper_sgmii_1g` (SGMII), `copper_sgmii_10g` (USXGMII). | #### SFP status object SFP status object has the following properties: ##### Object `SfpStatus` | Property | Type | Access | Description | | --- | --- | --- | --- | | `present` | boolean | read-only | Indicates whether an SFP module present in the port | | `eeprom_valid` | boolean | read-only | Indicates whether the SFP module has a valid EEPROM | | `supported` | boolean | read-only | Indicates whether the SFP module is supported | | `type` | string | read-only | SFP type read from EEPROM | | `power_good` | boolean | read-only | SFP port is powered | | `link` | boolean | read-only | link status | | `vendor_name` | string | read-only | vendor name | | `part_number` | string | read-only | part number | | `hardware_rev` | string | read-only | hardware revision | | `serial_number` | string | read-only | serial number | #### SFP API ##### Get SFP status ###### `GET /sfp/status` Returns the SFP status object Response `result`: SfpStatus Example request: ```http GET /api/v{version}/sfp/status HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "type": "copper_1g", "present": true, "link": true, "supported": true, "vendor_name": "SFP Vendor", "serial_number": "1122334455", "part_number": "SFP-V-Part-01R", "power_good": true, "hardware_rev": "A", "eeprom_valid": true } } ``` ##### Get SFP config Get the `SfpConfig` **Example request**: ```http GET /api/v{version}/sfp/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` **Example response**: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "sfp_type_forced": false, "sfp_type_forced_value": "", "available_sfp_types": [ "p2p_1g", "p2p_10g", "copper_1g", "copper_sgmii_1g", "copper_usxgmii_10g" ] } } ``` ##### Update SFP config ###### `PUT /sfp/config` *permission `settings` (inferred)* Request body (`application/json`): { sfp_type_forced: boolean, sfp_type_forced_value: string } Response `result`: SfpConfig Example request: ```http PUT /api/v{version}/sfp/config/ HTTP/1.1 Host: mafreebox.freebox.fr ``` ```json { "sfp_type_forced": true, "sfp_type_forced_value": "copper_1g" } ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "sfp_type_forced_value": "copper_1g", "sfp_type_forced": true, "available_sfp_types": [ "p2p_1g", "p2p_10g", "copper_1g", "copper_sgmii_1g", "copper_usxgmii_10g" ] } } ``` ## Update ### Update Status The Update API allows you to access box firmware update status #### Update status object Update status object have the following properties ##### Object `UpdateStatus` | Property | Type | Access | Description | | --- | --- | --- | --- | | `state` | string | | update current state Values: `initializing` (update process is initializing), `upgrading` (firmware is upgrading), `up_to_date` (firmware is up to date), `error` (an error occurred during update). | | `upgrade_state` | UpgradeState | | | #### Upgrade status object Details of current box upgrade. Only relevant for “upgrading” and “upgrade_failed” states. ##### Object `UpgradeState` | Property | Type | Access | Description | | --- | --- | --- | --- | | `state` | string | | upgrade state Values: `downloading` (downloading update), `download_failed` (update downloading has failed), `checking` (checking the downloaded data), `check_failed` (downloaded data check has failed), `prepare_write` (preparing to write data), `prepare_write_failed` (preparing to write data ha failed), `writing` (writing the data), `write_failed` (data writing has failed), `reread` (checking written data), `reread_failed` (written data checking has failed), `commit` (applying the update), `commit_failed` (update applying has failed). | | `old_version` | string | | current firmware version | | `new_version` | string | | new firmware version being downloaded | | `percent` | integer | | download progress if state is downloading | | `error_string` | string | | update error if state is download_failed | #### Update API ##### Get the update status ###### `GET /update/` Returns the Upgrade status object Response `result`: { state: string } Example request: ```http GET /api/v{version}/update/ HTTP/1.1 Host: mafreebox.freebox.fr ``` Example response: ```http HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ``` ```json { "success": true, "result": { "state": "auto_up_to_date" } } ``` ## Virtual machines ### VM API [UNSTABLE] This API allows to control VMs on boxes that have has_vm to true in their `SystemConfig` information. #### VM API Errors When attempting to access this API, you may encounter the following errors: | error_code | Description | | --- | --- | | initfail | VM cannot be initialized | | startfail | The VM cannot be launched | | inval | Invalid parameter | | nomem | Not enough memory available | | already_running | The VM is already running | | not_running | The VM is not running | | too_big | Size too big | | too_small | Size too small | | exists | File exists | | too_many_vms | The maximum number of configurable VMs has been reached | | no_such_vm | VM does not exist | | disk_in_use | The disk is already in use | | nocpu | Not enough CPUs available | | no_such_usb_port | USB port does not exist | | usb_in_use | Another VM is already using USB | | usb_init_fail | Unable to initialize USB | | disk_not_qcow2 | The disk is not in Qcow2 format | | unsupported_disk_type | Unsupported disk format | | file_not_found | Disk file not found | | efi_file_in_use | EFI settings file is already in use | | efi_file_fail | Cannot open EFI settings file | | distro_http | Internal http error | | distro_sig | Internal sig error | | distro_json | Internal json error | | create | Unable to create file | | perm_own | Incorrect permission | | open_info | Unable to open file for information | | open_resize | Cannot open file for resizing | | resize_trunc | Unable to resize raw disk | | power_button | Unable to send shutdown to VM | | restart | Cannot send restart to VM | | open_launch_disk | Error opening disk file | | open_launch_cd | Error opening cdrom file | | start_nodisk | Cannot start without disk | | init_vm_control | Unable to initialize VM control | | set_nodisk | Cannot set up a VM without disk | | set_badformat | Unsupported disk format | | save_data | Cannot save VM settings | | stop_control | Cannot stop VM control | | info | Unable to retrieve disk info | | info_parse | Unable to analyze disk information | | info_novirtual | Unable to retrieve disk size | | info_noactual | Unable to retrieve actual disk size | | info_noformat | Unable to retrieve disk format | | create_qcow | Unable to create qcow2 disk | | resize_qcow | Unable to resize qcow2 disk | | set_too_many_disks | The VM has too many disks | | set_empty_disk_path | Empty disk path | | task_notfound | The task does not exist | | not_stopped | The VM is not stopped | #### VM API objects ##### VM object ###### Object `VM` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | read-only | unique id of this VM | | `name` | string | | Name of this VM. Max 31 characters. | | `disk_path` | string | | Base64-encoded path to the hard disk image of this VM. | | `disk_type` | string | | Type of disk image. Values: `raw` (Raw disk data), `qcow2` (Qcow2 image type. Usually qcow version 3. Note: not all features are supported. In particular, reference to other images is disabled.). | | `cd_path` | string | | Base64-encoded path to CDROM device ISO image. Optional. | | `memory` | integer | | Memory allocated to this VM in megabytes. | | `vcpus` | integer | | Number of virtual CPUs to allocate to this VM. | | `status` | string | read-only | VM status Values: `stopped` (VM is stopped), `running` (VM is running), `starting` (VM is starting up. Transitional state), `stopping` (VM is being stopped. Transitional state). | | `enable_screen` | boolean | | Whether or not this VM should have a virtual screen, to use with the VNC websocket protocol. | | `bind_usb_ports` | string[] | | List of ports that should be bound to this VM. Only one VM can use USB at given time, whether is uses only one or all USB ports. The list of system USB ports is available in VmSystemInfo. For example: “usb-external-type-a”, “usb-external-type-c”. | | `enable_cloudinit` | boolean | | Whether or not to enable passing data through cloudinit. This uses the NoCloud iso image method; it will add a virtual cdrom drive (distinct from the one passed by cd_path) with the data in cloudinit_userdata and cloudinit_hostname when enabled. | | `cloudinit_hostname` | string | | When cloudinit is enabled, hostname desired for this VM. Max 59 characters. | | `cloudinit_userdata` | string | | When cloudinit is enabled, raw yaml to be passed in the user-data file. Maximum 32767 characters. | | `mac` | string | read-only | VM ethernet interface MAC address. | | `os` | string | | Type of OS used for this VM. Only used to set an icon for now. Example values: unknown fedora debian ubuntu freebsd opensuse centos jeedom homebridge | ##### VM System Info object ###### Object `VmSystemInfo` | Property | Type | Access | Description | | --- | --- | --- | --- | | `total_memory` | integer | read-only | Total memory available to VMs. | | `used_memory` | integer | read-only | Currently used memory by all VMs. | | `total_cpus` | integer | read-only | Total number of vCPUs available to VMs. | | `used_cpus` | integer | read-only | Currently used vCPUs by all VMs. | | `usb_ports` | string[] | read-only | List of USB ports available on this system | | `usb_used` | boolean | read-only | Whether a VM is currently using USB. (only one can use USB at a given time) | ##### VM Distribution object ###### Object `VmDistribution` | Property | Type | Access | Description | | --- | --- | --- | --- | | `name` | string | read-only | Name of downloadable distribution image. | | `url` | string | read-only | URL of distribution. Usually an arm64 qcow2 cloud image, supporting EFI boot and cloud-init. | | `hash` | string | read-only | Hash in the format sha256: or sha512:; or a URL to a SHA256SUMS or SHA512SUMS file (used by Ubuntu, Debian), or to a -CHECKSUM file (used by Fedora). It is designed to be passed as-is to the download add API. | | `os` | string | read-only | OS of this distribution image; to be passed as a os type in the VM. | ##### VM Disk info object ###### Object `VmDiskInfo` | Property | Type | Access | Description | | --- | --- | --- | --- | | `type` | string | read-only | Type of disk, just like in VM.disk_type | | `actual_size` | integer | read-only | Space used by virtual image on disk. This is how much filesystem space is consumed on the box. | | `virtual_size` | integer | read-only | Size of virtual disk. This is the size the disk will appear inside the VM. | ##### VM Disk task object ###### Object `VmDiskTask` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | read-only | Task id. | | `type` | string | read-only | Type of disk operation: create resize | | `done` | boolean | read-only | Is task done | | `error` | boolean | read-only | Is task in error | #### VM API actions ##### Get VM System Info ###### `GET /vm/info/` *permission `vm` (inferred) · unstable* Returns a VmSystemInfo Response `result`: VmSystemInfo ##### Get Installable VM distributions ###### `GET /vm/distros/` *permission `vm` (inferred) · unstable* Returns a collection of VmDistribution Response `result`: VmDistribution[] ##### Get the list of all VMs ###### `GET /vm/` *permission `vm` (inferred) · unstable* Returns a collection of VM Response `result`: VM[] ##### Get a VM ###### `GET /vm/{id}` *permission `vm` (inferred) · unstable* Returns a VM object | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response `result`: VM ##### Add a VM ###### `POST /vm/` *permission `vm` (inferred) · unstable* Needs to be passed a VM object Request body (`application/json`): VM Response `result`: VM ##### Delete a VM ###### `DELETE /vm/{id}` *permission `vm` (inferred) · unstable* Only works if vm is stopped. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). Only works if vm is stopped. ##### Update a VM ###### `PUT /vm/{id}` *permission `vm` (inferred) · unstable* Only works if vm is stopped. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). Only works if vm is stopped. ##### Start a VM ###### `POST /vm/{id}/start` *permission `vm` (inferred) · unstable* Only works if vm is stopped. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). Only works if vm is stopped. ##### Send a powerbutton signal to a VM ###### `POST /vm/{id}/powerbutton` *permission `vm` (inferred) · unstable* This will send an ACPI shutdown button event to the VM, so that it can decide to shutdown itself. Only works if vm is running. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). This will send an ACPI shutdown button event to the VM, so that it can decide to shutdown itself. Only works if vm is running. ##### Stop a VM Immediately stops the VM without any safety. ###### `POST /vm/{id}/stop` *permission `vm` (inferred) · unstable* Only works if vm is running. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). Only works if vm is running. ##### Reset a VM Immediately restarts the VM without any safety. ###### `POST /vm/{id}/restart` *permission `vm` (inferred) · unstable* Only works if vm is running. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). Only works if vm is running. ##### Watch for VM status changes You should use the websocket `RegisterAction` API with the `vm_state_changed` event to watch for changes in VM status, instead of polling. The event will contain this object: ###### Object `VmStateChange` | Property | Type | Access | Description | | --- | --- | --- | --- | | `id` | integer | read-only | VM id. | | `status` | string | read-only | New VM.status. | You can also watch for `lan_host_l3addr_reachable` and compare it with `VM.mac` to get the VM IP when it starts. ##### VM virtual console The serial port of the VM is available via a WebSocket. ###### `GET /vm/{id}/console` *permission `vm` (inferred) · unstable · WebSocket upgrade* It uses the QEMU websocket chardev device. Call must be authentified like the rest of the API. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: `101 Switching Protocols`. It uses the QEMU websocket chardev device. Call must be authentified like the rest of the API. ##### VM virtual screen When `VM.enable_screen` is `true`, the VM will have a VNC over websocket device available. ###### `GET /vm/{id}/vnc` *permission `vm` (inferred) · unstable · WebSocket upgrade* It uses the QEMU VNC websocket device. Call must be authentified like the rest of the API. This device should work with noVNC unmodified. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: `101 Switching Protocols`. It uses the QEMU VNC websocket device. Call must be authentified like the rest of the API. This device should work with noVNC unmodified. ##### Get information on a virtual disk ###### `POST /vm/disk/info` *permission `vm` (inferred) · unstable* Returns a VmDiskInfo object. Request body (`application/json`): { disk_path: string } Response `result`: VmDiskInfo Returns a `VmDiskInfo` object. ##### Create a virtual disk ###### `POST /vm/disk/create` *permission `vm` (inferred) · unstable* Returns a task id. Task should not be polled, use the vm_disk_task_done websocket event with RegisterAction. Request body (`application/json`): { disk_path: string, size: integer, disk_type: string } Response `result`: integer Returns a task id. Task should not be polled, use the `vm_disk_task_done` websocket event with `RegisterAction`. ##### Resize a virtual disk ###### `POST /vm/disk/resize` *permission `vm` (inferred) · unstable* Returns a task id. Task should not be polled, use the vm_disk_task_done websocket event with RegisterAction. Request body (`application/json`): { disk_path: string, size: integer, shrink_allow: boolean } Response `result`: integer Returns a task id. Task should not be polled, use the `vm_disk_task_done` websocket event with `RegisterAction`. ##### Get a virtual disk task ###### `GET /vm/disk/task/{id}` *permission `vm` (inferred) · unstable* Returns a VmDiskTask | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response `result`: VmDiskTask Returns a `VmDiskTask` ##### Delete a virtual disk task ###### `DELETE /vm/disk/task/{id}` *permission `vm` (inferred) · unstable* Delete your tasks once they are done. | Parameter | In | Type | Description | | --- | --- | --- | --- | | `id` | path | string | | Response: no result schema documented (envelope `{ "success": true }`). Delete your tasks once they are done. ## API changes history ### Api changes from version 16.0 to 16.1 #### API change (v16.1) ##### DHCP - Added option 15 (domain_name) ##### LAN - Added local_domain parameter to LanConfig - Increase maximum host domain_name size from 63 to 255 - Refuse duplicate static route prefixes ### Api changes from version 15.0 to 16.0 #### API change (v16.0) - Added API to configure the limited edition ledstrip activation planning. - Added API to configure the TFTP server - The ‘options’ field has been added to the DHCP API. This field can be used to configure the DHCP options included in the replies from the DHCP server. - Added API to configure the limited edition ledstrip activation planning. - Added API to configure the screensaver animation on compatible boxes. - Added API to configure static IPv4 routes. - Added ‘domain_name’ field in LanHost object to configure a local domain name. - Added the Wi-Fi steering config API. ### Api changes from version 14.0 to 15.0 #### API change (v15.0) ##### File system - The file listing API returns an object rather than simply an array of entries - The file listing API supports pagination ### Api changes from version 13.0 to 14.0 #### API change (v14.0) ##### Wifi - Add new BSS encryption value wpa23_psk_ccmp_mrsno. When targeting an api version older than 14, this new encryption value is replaced by wpa2_psk_ccmp. - Add new gcmp256 field in BSS config. - Add new BSS info to inform if access point supports wep encryption or not - The guest wifi is now using a dedicated network, and the name of the network can be changed. Use the WifiCustomKeyConfig api to enable/configure it. - Added support for MLO (Multi Link Operation) configurations. See the MLOConfig API ##### Lan browser - Add new lan host types. - Add categories to lan/browser/types API. #### API Update ##### LCD Configuration - Add hide_led parameter to control the power LED on supported Freebox models ### Api changes from version 12.2 to 13.0 #### API change (v13.0) ##### Wifi - The WifiApStatus field of WifiAp object has a new value ‘disabled_temp’ when AP is disabled temporarily. - A new field named ‘temp_disable_remaining_time’ has been added to WifiAp object. - Add API /wifi/temp_disable ### Api changes from version 12.1 to 12.2 #### API change (v12.2) ##### LCD - Add settings to control Freebo Ultra Limited Edition LED strip configuration ##### System - Add capability flag to know if the Freebox Model supports LED strip configuration ### Api changes from version 12.0 to 12.1 #### API change (v12.1) ##### File System - Add exifMode optional parameter to file list API to get exif data from supported images (jpeg, heic) ##### Wifi - WifiCustomKeyParams can now have a max_use_count of 0. This means the key has no restriction of how many users can use it to associate to the ap. ### Api changes from version 11.2 to 12.0 #### API change (v12.0) ##### Wifi - The WifiApStatus field of WifiAp object has a new value stopping when a stop operation is pending due to param or disabled state - The WifiAllowedComb object now have a psc field to indicate that this channel combination is using a Primary Scanning Channel (PSC) ##### Notifications - Add new lan_host notification type to be notified when a new host is connected to the box for the first time - Add new password_change notification type to be notified when the admin password has been changed ### Api changes from version 11.1 to 11.2 #### New API (v11.2) ##### File system - Add api to get a FileInfo list from a list of file paths ### Api changes from version 11.0 to 11.1 #### API change (v11.1) ##### System - The SystemModelInfo object can contain additional fields to indicate Eco-WiFi and WOP support ##### IPv6 Connection - Add ipv6_prefix_firewall field to IPv6 configuration object, in order to enable the IPv6 firewall on secondary prefixes ### Api changes from version 10.2 to 11.0 #### New API (v11.0) ##### Update - API to get the box update status ##### Standby - API to configure box standby (either WiFi or box standby) ##### System - API to shutdown box ##### SFP - API to configure LAN SFP port on supported platforms #### API change (v11.0) ##### Notification - Update notification API to be able to customize notification server ##### Wifi - Add custom_key_ssid to BSS status - Standby API supersedes WiFi planning API (which may be removed in the future) ### Api changes from version 10.1 to 10.2 #### New API (v10.2) ##### Wifi State - Add wifi global state API - Deprecate expected_phys in wifi global configuration API ### Api changes from version 10.0 to 10.1 #### Changed API (v10.1) ##### Call Api Changes - Expose phone number associated with the subscription - Expose voicemails left on the line ### Api changes from version 9.1 to 10.0 #### Deprecated API (v10.0) - The Connection API for xDSL/4G aggregation is no longer usable. It has been replaced by separate endpoints providing respectively LTE connection status and aggregation status. #### Changed API (v10.0) - The Connection API has been changed to not mix aggregation and LTE connection status. - The Connection API exposes Internet Backup connection status. ### Api changes from version 9.0 to 9.1 #### Changed API (v9.1) - New diagnostics API for network throughput slowness detection. ### Api changes from version 8.5 to 9.0 #### Changed API (v9.0) - WiFi API was extended to support 6Ghz band and 802.11ax (HE) ### Api changes from version 8.4 to 8.5 #### Changed API (v8.5) - Camera API does not require “camera” permission any more to list cameras. The permission is still needed to access camera records and live stream. - Add camera lan id in camera API result to find the corresponding lan host in lan browser API. - Add API to retrieve channel survey history ### Api changes from version 8.3 to 8.4 #### Changed API (v8.4) - New Wifi api error code ‘inval_wps_hidden_ssid’ when trying to enable WPS with hidden SSID. ### Api changes from version 8.2 to 8.3 #### New API (v8.3) - Added File System Advice API to help user configure the storage attached to the Freebox. ### Api changes from version 8.1 to 8.2 A new way to discover a remote connection port change has been added. It is recommended to implement it as fallback mechanism, since the port can now change automatically once unreachable over IPv4. #### Changed API (v8.2) - New LAN browser device type (car): `LanHost.host_type`. - File system task now have source and destination info: `FsTask.from` - Fix file system rm issue preventing status to be correctly updated #### Newly documented API (v8.2) - RAID API is now documented. It is still considered unstable. - VM API is now documented. It is still considered unstable. - WebSocket event API has now additional documentation. #### New API (v8.2) - Added Language API to allow changing box language. ### Api changes from version 8.0 to 8.1 #### New API (v8.1) - Wifi has a new diagnostic API - New language API ### Api changes from version 7.0 to 8.0 #### Deprecated API (v8.0) - Parental control API is no longer usable. It has been replaced by the Profile API. #### New API (v8.0) - Profile API is simpler to use and replaces parental control API. ### Api changes from version 6.0 to 7.0 #### Changed API (v7.0) - The api_version contains less information when called unauthenticated and remotely. #### New API (v7.0) - Added VM API for Freebox Delta. ### Api changes from version 5.0 to 6.0 #### Changed API (v6.0) - Added optional ‘filename’ parameter, to download “Add by url” api. #### New API (v6.0) - Added Home API - Added Player API - Added Notification API ### Api changes from version 4.0 to 5.0 #### Deprecated api (v5.0) - The old upload api as been deprecated since v4 in favor of the WebSocket upload api. The v3 upload api will be removed in next firmware release. All new apps should only use websocket upload api. However tracking of uploads has not been changed. #### Changed API (v5.0) - Added ‘wps_enabled’, ‘wps_uuid’ to `WifiBssConfig` wps configuration - Changed `WifiBss` logic to expose both ‘bss_params’ and ‘shared_bss_params’ and telling which one is currently used with the new field ‘use_shared_params’. This replaces the ‘use_default_config’ from `WifiBssConfig` and ‘is_main_bss’ from `WifiBssStatus` #### New API (v5.0) - Added wifi `WifiCustomKey` api - Added wifi `WifiWpsSession` api - Added wifi `DHCPv6Config` api ### Api changes from version 3.0 to 4.0 #### Secure Access - The Freebox OS API can now be reached over HTTPS. All applications MUST switch to https access. Unsecure access will be removed at some point. #### Deprecated api (v4) - The old upload api as been deprecated in favor of the WebSocket upload api. The v3 upload api will be removed in next firmware release. All new apps should only use websocket upload api. However tracking of uploads has not been changed. #### Changed API - The File System api now return more details error codes, and can now return ‘access_denied’ and ‘disk_full’ in case of IO errors - `SystemConfig` has new ‘disk_status’, ‘box_flavor’ attributes - `ConnectionStatus` now expose ‘ipv4_port_range’ for customers that don’t have a ‘full’ IPv4 - Added new ‘port_outside_range’ error_code when attempting to use a port outside of assigned ‘ipv4_port_range’ - Added ‘remote_access_min_port’ and ‘remote_access_max_port’ to `ConnectionConfiguration` - Added ‘min_port’, ‘max_port’ for `IncomingPortConfig`, `VPNServerConfig` - Added ‘readonly’ for `IncomingPortConfig` - Added ‘allow_remote_access’ for `FtpConfig` - Added ‘mark_all_as_read’ and ‘delete_all’ for Call api - Added ‘enabled_ipv6’ and ‘node_count_ipv6’ for `DhtStats` - Added ‘preview_url’ to `DownloadFile` for bittorrent downloads - Added ‘info_hash’, ‘piece_length’ to `Download` for bittorrent downloads #### New API (v4) - Added `StorageConfig` api - Added Download Pieces information ### Api changes from version 2.0 to 3.0 #### Connection api Changes (v3) - Added a ginp, rtx_tx, rtx_c, rtx_uc property to `XdslStats` #### New API (v3) - Some tv, epg and pvr api have been added. Those api are undocumented and should be considered UNSTABLE (may be modified without further notice). ### Api changes from version 1.1 to 2.0 #### Download Api Changes - Added 2 new error_code: invalid_address port_conflict - Added a new *‘cookies’* parameter when adding a download by url. This allow browser plugins to pass cookies along with url. This can be useful for session based authentication. - Added new `DownloadStats` attributes: conn_ready nb_peer blocklist_entries blocklist_hits dht_stats - Deprecate path attribute for `DownloadFile` - Add new attributes to `DownloadFile` filepath name mimetype - Added a blacklist API to control bittorrent peers blacklist entries #### Download Configuration Api Changes - Added new `DownloadConfiguration` attributes main_port dht_port #### UPnP IGD Api Changes - Added a host property to `UPnPRedir` #### Connection api Changes (v2) - Added a ipv6ll property to `ConnectionIpv6Configuration` - Added a snr_10, attn_10 property to `XdslStats` #### RRD Api Changes - Added new entries for net database: vpn_rate_down vpn_rate_up - Added new entries for temp database: cpum cpub sw hdd fan_speed - Deprecate entries for temp database: temp1 temp2 temp3 #### System Api Changes - Added uptime_val attribute to `SystemConfig` #### Wifi Api Changes - Completely rework Wifi API to be able to handle multiple Access Points. #### New API (v2) - Added an Incoming port configuration Api - Added a VPN Client Api - Added a VPN Server Api