Download PDF

Metadata API.

Within SamKnows One you are able to attach metadata to measurement agents such as package, ISP, timezone or custom fields such as exchange. This API allows you to modify and view metadata of measurement agents.

For more information on metadata please consult our SamKnows One Documentation here.

The Metadata API is a JSON based with all requests and responses using JSON. This API requires an access token which should be passed in the HTTP Authentication header. All communication should be over HTTP with TLS 1.2.

Please read general documentation of APIs here before continuing.

Development

Developer documentation is available below. URLs for production and development purposes will be provided upon commencement of a project. Authentication tokens are managed through the SamKnows One UI.

Performance and capacity

We actively manage capacity planning to ensure that it can handle as many simultaneous connections/sessions as required by our clients, it has been load tested to be able to handle thousands of hits per minute and scales easily and linearly. Requests usually respond within a couple of hundred milliseconds.

Logging

API call counts are logged for auditing purposes.

Authentication

All requests to the Metadata Updates API require authentication using a HTTP Authorization header and a valid token. This token is provided by SamKnows and generated from within SamKnows One.

Example: HTTP authorization header

Authorization: Bearer <token>

Example: Authentication failure

If the request cannot be authentication a HTTP 403 response will be returned.

+ Response 403 (application/json)

          + Body

                    {
                      "code": "ACCESS_DENIED",
                      "message": "Access Denied",
                    }

Updating metadata of measurement agents [PUT /metadata]

This endpoint allows you to modify the metadata of an individual measurement agents.

Body fields

FieldDescriptionTypeAllowed valuesExampleRequired
agentThe data in here is the data used to select the agent to modify the metadata ofobjectSee below{"mac_address": "0E00847AD801"}Yes
metadataIn this blob you can specify the fields you wish to modify, available fields are listed belowobjectSee below{"package": "AcmeCorp:100x20"}Yes
backdate_fromYou can specify a UNIX time stamp of the date from which this metadata will be applied, if not specified it will default to today. This allows you to set an agent to have changed package in the past and have this reflected in SamKnows One.integerUNIX timestamps not more than 28 days old1531991804No
overwrite_allSpecifying true here will remove any other metadata values currently specified. For example, if a package is set and you do not define a package in your request, the package will be nulled; if you are setting new custom metadata, it will overwrite any existing, rather than merging with what was already there. This defaults to false (only updating what you specify) when not specified.booleantrue, falsefalseNo
Specifying agent(s) to modify

In order to specify an agent, you can specify as many different criteria as you wish and any measurement agents that match this criteria will have the modification performed. In the majority of situations where you're only modifying a single agent, we recommend using a unique key such as agent_id, unit_id, MAC address or a custom metadata field such as customer number.

If no measurement agents are applicable then you will receive a 404.

The 'standard' fields you can use are:

FieldDescriptionTypeExample
agent_idThe SamKnows-generated agent_idstring3c736caa-be23-4e4b-b39d-2adc4ae4ff48
unit_idThe SamKnows-generated unit_idinteger1029617
mac_addressThe MAC address provided to SamKnows infrastructure on registrationstring0E00847AD801
ispThe name of an ISP, matching how it is stored in the SamKnows databasestringAcmeCorp
packageAn ISP:Package pair to match measurement agents bystringAcmeCorp:100x20
timezoneThe IANA timezone an agent is located instringEurope/London
customSet of key-values containing custom metadata to match by. If set, must contain at least one key-value.object{"country": "England", "region": "London"}
New metadata

Any measurement agents that match will have their metadata changed to the values you specify.

The 'standard' fields you can use are:

FieldDescriptionTypeExample
packageAn ISP:Package pair to set against the measurement agents. It is possible to specify just the Isp by just including the ISP name for example AcmeCorp:. In this case, the measurement agents will be set the Isp and have any existing package removed.stringAcmeCorp:100x20
timezoneThe IANA timezone an agent is located instringEurope/London
customSet of key-values containing the new custom metadata. Will merge with existing unless overwrite_all set. If set must contain at least one key-value.object{"country": "England", "region": "London"}

You can find out more about custom metadata fields including their identifiers from within SamKnows One in the Metadata Management UI.

Example: Updating agent metadata

+ Request (application/json)

+ Headers

Accept: application/json

Authorization: Bearer &lt;token&gt;

+ Body

{

"agent": {

"mac_address": "0E00847AD801"

},

"metadata": {

"package": "AcmeCorp:100x20",

"timezone": "Europe/London",

"custom": {

"exchange": "THFJ",

"postcode": "GU10",

"sync_speed": 38

}

},

"backdate_from": 1531991804,

"overwrite_all": false

}

+ Response 200 (application/json)

+ Body

{

"code": "OK",

"message": "Request successful"

}</code></pre>

View an agent's current metadata [GET /metadata/{field}/{value}]

This endpoint enables the retrieval of a single agent's current metadata

URL query parameters

You can specify one of three fields in the

FieldDescriptionTypeExampleagentThe SamKnows-generated agent_id with non-alphanumeric chars removedstring3c736caabe234e4bb39d2adc4ae4ff48unitThe SamKnows-generated unit_idinteger1029617macThe MAC address provided to SamKnows infrastructure on registration with non-alphanumeric chars removedstring0E00847AD801

So a resulting endpoint might be GET /metadata/mac/0E00847AD801.

Example: Retrieving an agent's current metadata

+ Request (application/json)

          + Headers

                  Accept: application/json
                  Authorization: Bearer <token>

      + Response 200 (application/json)

          + Body

              {
                    "code": "OK",
                    "message": "Request successful",
                    "data": {
                          "package": "AcmeCorp:100x20",
                          "isp": "AcmeCorp",
                          "timezone": "Europe/London",
                          "custom": {
                              "exchange": "THFJ",
                              "postcode": "GU10",
                              "sync_speed": 38
                          }
                    }
              }

Force an internal server error (HTTP 500 status code) [GET /response-internal-server-error]

Example

+ Response 500
          + Body

                      {
                          "code": "UNKNOWN_ERROR",
                          "message": "An unexpected error has occurred. This has been reported to our engineering teams, please try again shortly.",
                      }

Errors

If an error occurs while processing a request to the Metadata API, you may receive the following error:

+ Response 500 (application/json)

          + Body

                      {
                          "code": "UNKNOWN_ERROR",
                          "message": "An unexpected error has occurred. This has been reported to our engineering teams, please try again shortly.",
                      }

When we could not match any metadata to update:

+ Response 404 (application/json)

          + Body

                      {
                          "code": "NOT_FOUND",
                          "message": "Not found"
                      }

When retrieving for a non-existent unit:

+ Response 404 (application/json)

          + Body

                      {
                          "code": "NOT_FOUND",
                          "message": "Not found"
                      }

When trying to match by Agent using an identifier which is not a string:

+ Response 422 (application/json)

          + Body

                      {
                          "code": "VALIDATION_FAIL",
                          "message": "Validation failed",
                          "errors": {
                              "agent[agent_id]": [
                                  "This value should be of type string."
                              ]
                          }
                      }

When trying to match by Unit using an identifier which is not an integer:

+ Response 422 (application/json)

          + Body

                      {
                          "code": "VALIDATION_FAIL",
                          "message": "Validation failed",
                          "errors": {
                              "agent[unit_id]": [
                                  "This value should be of type integer."
                              ]
                          }
                      }

When trying to match by a package which is not in the IspName:PackageName format:

+ Request (application/json)

          + Headers

                  Accept: application/json
                  Authorization: Bearer <token>

          + Body

                  {
                        "agent": {
                              "package": "200x10"
                        },
                        "metadata": {
                              "package": "AcmeCorp:100x20",
                              "timezone": "Europe/London",
                              "custom": {
                                  "exchange": "THFJ",
                                  "postcode": "GU10",
                                  "sync_speed": 38
                              }
                        },
                        "backdate_from": 1531991804,
                        "overwrite_all": false
                  }

      + Response 422 (application/json)

          + Body

                      {
                          "code": "VALIDATION_FAIL",
                          "message": "Validation failed",
                          "errors": {
                              "agent[package]": [
                                  "200x10 is not a valid package name."
                              ]
                          }
                      }

When trying to match by Timezone using an identifier which is not a string:

+ Response 422 (application/json)

          + Body

                      {
                          "code": "VALIDATION_FAIL",
                          "message": "Validation failed",
                          "errors": {
                              "agent[timezone]": [
                                  "This value should be of type string."
                              ]
                          }
                      }

When attempting to match using null custom metadata:

+ Response 422 (application/json)

          + Body

                      {
                          "code": "VALIDATION_FAIL",
                          "message": "Validation failed",
                          "errors": {
                              "agent[custom]": [
                                  "Cannot search for null custom metadata."
                              ]
                          }
                      }

When attempting to match using empty custom metadata:

+ Response 422 (application/json)

          + Body

                      {
                          "code": "VALIDATION_FAIL",
                          "message": "Validation failed",
                          "errors": {
                              "agent[custom]": [
                                  "Must specify at least one key when searching by custom fields."
                              ]
                          }
                      }

When attempting to match using a custom metadata field that contains less than one letter:

+ Request (application/json)

          + Headers

                  Accept: application/json
                  Authorization: Bearer <token>

          + Body

                  {
                        "agent": {
                              "custom": {"0": "value"}
                        },
                        "metadata": {
                              "package": "AcmeCorp:100x20",
                              "timezone": "Europe/London",
                              "custom": {
                                  "exchange": "THFJ",
                                  "postcode": "GU10",
                                  "sync_speed": 38
                              }
                        },
                        "backdate_from": 1531991804,
                        "overwrite_all": false
                  }

      + Response 422 (application/json)

          + Body

                      {
                          "code": "VALIDATION_FAIL",
                          "message": "Validation failed",
                          "errors": {
                              "agent[custom][0]": [
                                  "Invalid key"
                              ]
                          }
                      }

When omitting the agent key from the request:

+ Request (application/json)

          + Headers

                  Accept: application/json
                  Authorization: Bearer <token>

          + Body

                  {
                        "metadata": {
                              "package": "AcmeCorp:100x20",
                              "timezone": "Europe/London",
                              "custom": {
                                  "exchange": "THFJ",
                                  "postcode": "GU10",
                                  "sync_speed": 38
                              }
                        },
                        "backdate_from": 1531991804,
                        "overwrite_all": false
                  }

      + Response 422 (application/json)

          + Body

                      {
                          "code": "VALIDATION_FAIL",
                          "message": "Validation failed",
                          "errors": {
                              "agent": [
                                  "Agent cannot be empty."
                              ]
                          }
                      }

When attempting to update by package and not using the IspName:PackageName format:

+ Request (application/json)

          + Headers

                  Accept: application/json
                  Authorization: Bearer <token>

          + Body

                  {
                        "agent": {
                              "custom": {"field": "value"}
                        },
                        "metadata": {
                              "package": "80x10",
                              "timezone": "Europe/London",
                              "custom": {
                                  "exchange": "THFJ",
                                  "postcode": "GU10",
                                  "sync_speed": 38
                              }
                        },
                        "backdate_from": 1531991804,
                        "overwrite_all": false
                  }

      + Response 422 (application/json)

          + Body

                      {
                          "code": "VALIDATION_FAIL",
                          "message": "Validation failed",
                          "errors": {
                              "metadata[package]": [
                                  "80x10 is not a valid package name."
                              ]
                          }
                      }

When attempting to update to a package where the ISP does not exist:

+ Request (application/json)

          + Headers

                  Accept: application/json
                  Authorization: Bearer <token>

          + Body

                  {
                        "agent": {
                              "custom": {"field": "value"}
                        },
                        "metadata": {
                              "package": "AcmeCorp:80x10",
                              "timezone": "Europe/London",
                              "custom": {
                                  "exchange": "THFJ",
                                  "postcode": "GU10",
                                  "sync_speed": 38
                              }
                        },
                        "backdate_from": 1531991804,
                        "overwrite_all": false
                  }

      + Response 422 (application/json)

          + Body

                      {
                          "code": "VALIDATION_FAIL",
                          "message": "Validation failed",
                          "errors": {
                              "metadata[package]": [
                                  "Unable to resolve new package AcmeCorp:80x10. (Invalid Isp name in new package)"
                              ]
                          }
                      }

When attempting to update to a package where the package does not exist:

+ Request (application/json)

          + Headers

                  Accept: application/json
                  Authorization: Bearer <token>

          + Body

                  {
                        "agent": {
                              "custom": {"field": "value"}
                        },
                        "metadata": {
                              "package": "AcmeCorp:80x10",
                              "timezone": "Europe/London",
                              "custom": {
                                  "exchange": "THFJ",
                                  "postcode": "GU10",
                                  "sync_speed": 38
                              }
                        },
                        "backdate_from": 1531991804,
                        "overwrite_all": false
                  }

      + Response 422 (application/json)

          + Body

                      {
                          "code": "VALIDATION_FAIL",
                          "message": "Validation failed",
                          "errors": {
                              "metadata[package]": [
                                  "Unable to resolve new package AcmeCorp:80x10. (Invalid Package name in new package)"
                              ]
                          }
                      }

When attempting to update to an invalid timezone:

+ Request (application/json)

          + Headers

                  Accept: application/json
                  Authorization: Bearer <token>

          + Body

                  {
                        "agent": {
                              "custom": {"field": "value"}
                        },
                        "metadata": {
                              "package": "AcmeCorp:80x10",
                              "timezone": "Africa/London",
                              "custom": {
                                  "exchange": "THFJ",
                                  "postcode": "GU10",
                                  "sync_speed": 38
                              }
                        },
                        "backdate_from": 1531991804,
                        "overwrite_all": false
                  }

      + Response 422 (application/json)

          + Body

                      {
                          "code": "VALIDATION_FAIL",
                          "message": "Validation failed",
                          "errors": {
                              "metadata[timezone]": [
                                  "Africa\/London is not a valid IANA timezone."
                              ]
                          }
                      }

When attempting to update custom metadata with numeric keys:

+ Request (application/json)

          + Headers

                  Accept: application/json
                  Authorization: Bearer <token>

          + Body

                  {
                        "agent": {
                              "custom": {"field": "value"}
                        },
                        "metadata": {
                              "package": "AcmeCorp:80x10",
                              "timezone": "Europe/London",
                              "custom": {
                                  "0": "THFJ"
                              }
                        },
                        "backdate_from": 1531991804,
                        "overwrite_all": false
                  }

      + Response 422 (application/json)

          + Body

                      {
                          "code": "VALIDATION_FAIL",
                          "message": "Validation failed",
                          "errors": {
                              "metadata[custom][0]": [
                                  "Invalid key"
                              ]
                          }
                      }

When attempting to update custom metadata without specifying any keys:

+ Request (application/json)

          + Headers

                  Accept: application/json
                  Authorization: Bearer <token>

          + Body

                  {
                        "agent": {
                              "custom": {"field": "value"}
                        },
                        "metadata": {
                              "package": "AcmeCorp:80x10",
                              "timezone": "Europe/London",
                              "custom": {}
                        },
                        "backdate_from": 1531991804,
                        "overwrite_all": false
                  }

      + Response 422 (application/json)

          + Body

                      {
                          "code": "VALIDATION_FAIL",
                          "message": "Validation failed",
                          "errors": {
                              "metadata[custom]": [
                                  "Must specify at least one key when updating custom fields."
                              ]
                          }
                      }

When attempting to set custom metadata to null:

+ Request (application/json)

          + Headers

                  Accept: application/json
                  Authorization: Bearer <token>

          + Body

                  {
                        "agent": {
                              "custom": {"field": "value"}
                        },
                        "metadata": {
                              "package": "AcmeCorp:80x10",
                              "timezone": "Europe/London",
                              "custom": null
                        },
                        "backdate_from": 1531991804,
                        "overwrite_all": false
                  }

      + Response 422 (application/json)

          + Body

                      {
                          "code": "VALIDATION_FAIL",
                          "message": "Validation failed",
                          "errors": {
                              "metadata[custom]": [
                                  "Cannot null custom metadata."
                              ]
                          }
                      }

When setting a backdate which is not a valid integer:

+ Request (application/json)

          + Headers

                  Accept: application/json
                  Authorization: Bearer <token>

          + Body

                  {
                        "agent": {
                              "custom": {"field": "value"}
                        },
                        "metadata": {
                              "package": "AcmeCorp:80x10",
                              "timezone": "Europe/London",
                              "custom": {"field": "value"}
                        },
                        "backdate_from": "something",
                        "overwrite_all": false
                  }

      + Response 422 (application/json)

          + Body

                      {
                          "code": "VALIDATION_FAIL",
                          "message": "Validation failed",
                          "errors": {
                              "backdate_from": [
                                  "Invalid backdate (\"something\"). Must be a valid integer."
                              ]
                          }
                      }

When setting a backdate not in the last 28 days:

+ Request (application/json)

          + Headers

                  Accept: application/json
                  Authorization: Bearer <token>

          + Body

                  {
                        "agent": {
                              "custom": {"field": "value"}
                        },
                        "metadata": {
                              "package": "AcmeCorp:80x10",
                              "timezone": "Europe/London",
                              "custom": {"field": "value"}
                        },
                        "backdate_from": 0,
                        "overwrite_all": false
                  }

      + Response 422 (application/json)

          + Body

                      {
                          "code": "VALIDATION_FAIL",
                          "message": "Validation failed",
                          "errors": {
                              "backdate_from": [
                                  "Invalid backdate (0). Must be in last 28 days."
                              ]
                          }
                      }

When setting a backdate not in the last 28 days:

+ Request (application/json)

          + Headers

                  Accept: application/json
                  Authorization: Bearer <token>

          + Body

                  {
                        "agent": {
                              "custom": {"field": "value"}
                        },
                        "metadata": {
                              "package": "AcmeCorp:80x10",
                              "timezone": "Europe/London",
                              "custom": {"field": "value"}
                        },
                        "backdate_from": 0,
                        "overwrite_all": false
                  }

      + Response 422 (application/json)

          + Body

                      {
                          "code": "VALIDATION_FAIL",
                          "message": "Validation failed",
                          "errors": {
                              "backdate_from": [
                                  "Invalid backdate (0). Must be in last 28 days."
                              ]
                          }
                      }

When overwrite_all is not a boolean:

+ Request (application/json)

          + Headers

                  Accept: application/json
                  Authorization: Bearer <token>

          + Body

                  {
                        "agent": {
                              "custom": {"field": "value"}
                        },
                        "metadata": {
                              "package": "AcmeCorp:80x10",
                              "timezone": "Europe/London",
                              "custom": {"field": "value"}
                        },
                        "overwrite_all": "something"
                  }

      + Response 422 (application/json)

          + Body

                      {
                          "code": "VALIDATION_FAIL",
                          "message": "Validation failed",
                          "errors": {
                              "overwrite_all": [
                                  "This value should be of type bool."
                              ]
                          }
                      }