Back to top

CamTrace metadata connector API v1

Overview

This document describes the process of creating a CamTrace metadata connector.

Change log

VersionDateAuthorChanges
1.0-0125/01/2017Olivier PELETFirst version
1.0-0203/08/2022Romain RIGOTMultiple adaptations for CT-Server v16.0.0 new metadata system
1.0-0314/03/2023Romain RIGOTFixed schema and parameter description of WS SEND event, GET /events/labels and POST /events/search
1.0-0429/03/2023Romain RIGOTEvent types names agreement
1.0-0530/03/2023Romain RIGOTEvent search mandatory criteria
1.0-0622/05/2023Romain RIGOTEvent search response order
1.0-0720/07/2023Romain RIGOTPOST /events route, total number of events in search result
1.0-0814/02/2024Romain RIGOTGET /events/labels route, params translation

What is a metadata connector ?

A metadata connector is a module which is able to retrieve, store and notify events coming from a device. It takes the form of an web application which can requests and responds to HTTP requests, using JSON messages (REST paradigm).

The application has an HTTP entrypoint and must implement a set of mandatory routes. It is also a websocket server on which CT-Server will connect to receive Events notifications (pull point)

It is langage agnostic and can be hosted on any computer on your network.

Architecture

Global architecture

Image

Exchanges between CamTrace server and connector

Image

Authentication

All mandatory routes implemented in your connector must be authenticated using HTTP basic authentication.

If your connector uses on static ressources, such as css or javascript files, you have to put these files behind the route /static and disable authentication for this route and subroutes.

Register a connector

  • In order to register your connector, you have to go to the CamTrace server administration interface in Manage/Metadata and click on Add new device Image

  • Enter the name of your device, select "External connector" as the Connector type, indicate the entrypoint URL of your API, this is from where your implemented routes will be called. You have to specify a name, optionnaly a login / password and an associated camera which will be associated to your connector and used in CT-Client displays. Then click on save button. Image

  • Your connector is now registered with the CamTrace server Image

HTTP status codes

  • 200 OK Successful request

  • 201 Created New object saved

  • 400 Bad Request Bad request input

  • 401 Unauthorized Error in request authentication

  • 404 Not found No such object

  • 500 Internal Server Error Something went wrong

  • 503 Service Unavailable The service is currently unavailable

Configuration

The configuration allows the CT-Server to retreive the websocket endpoint of your connector in order to establish a permanant connection (as long as CT-Server video services are up and connector is not ignored).

GET configuration

Update configuration
GET/config

This route is called when you register your add or edit your connector into the CT server (see Register a connector). It gives your connector the credentials and the endpoint needed to communicate with the CamTrace server’s API.

Example URI

GET /api/v1/config
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "pullpointUrl": "http://127.0.0.1:8090/ws/events",
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "apiEndpoint": {
      "type": "string",
      "description": "Connector websocket endpoint for events notifications"
    }
  }
}

Health

Health
GET/health

This route is called by the CamTrace web interface is order to check the connector status.

When everything is fine you must return the HTTP code 200.

If there is an issue somewhere in your connector (missing database, down devices…) you must return the HTTP code 503.

Example URI

GET /api/v1/health
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "status": "The connector is up and running"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "status": {
      "type": "string",
      "description": "Status message"
    }
  },
  "required": [
    "status"
  ]
}
Response  503
HideShow
Headers
Content-Type: application/json
Body
{
  "status": "One of the device is not ready"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "status": {
      "type": "string",
      "description": "Status message"
    }
  },
  "required": [
    "status"
  ]
}

Admin

admin
GET/admin

This route is not part of the API and is optionnal

This uri can serve your connector administration webpage if needed. If it exists, it create a links to this page in the CT-Server webadmin connector section.

To show it's difference from the API, this URL must directly takes place under the root virtual directory of the connector server and port.

Example URI

GET /admin

Events

Get labels

Get labels
GET/events/labels

The CamTrace client needs to know which label to display when it receive new event from a connector. This method must return a labels object, a descriptions object and a params object containing a label and a more verbose description of all events handled by your connector.

Image

Every property of the label, description and params objects refers to an event type. Event types names are up to the connector creators but all of this events belongs to an external prefix / property which is the external events category name in Camtrace system. Every value of a property is a string. For the descriptions part, it may contains one or several JSON pointers to event arguments present in the description part of your events (ex: %{/customParams/demoParam}). These tags will be replaced dynamically by Camtrace clients during display of live events.

Example URI

GET /api/v1/events/labels
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "labels": {
    "external.camtracetest1": "CamTrace event test 1",
    "external.camtracetest2": "CamTrace event test 2"
  },
  "descriptions": {
    "external.camtracetest1": "CamTrace event test 1 from %{/customParams/demoParam}",
    "external.camtracetest2": "CamTrace event test 2 from %{/customParams/demoParam}"
  },
  "params": {
    "external": {
      "camtracetest1": "Test 1",
      "camtracetest2": "Test 2 "
    }
  }
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "labels": {
      "type": "object",
      "properties": {
        "external.camtracetest1": {
          "type": "string"
        },
        "external.camtracetest2": {
          "type": "string"
        }
      },
      "description": "An object describing the label for each event handled by the connector"
    },
    "descriptions": {
      "type": "object",
      "properties": {
        "external.camtracetest1": {
          "type": "string"
        },
        "external.camtracetest2": {
          "type": "string"
        }
      },
      "description": "An object describing the description for each event handled by the connector"
    }
  },
  "params": {
    "type": "object",
    "properties": {
      "external": {
        "type": "object",
        "properties": {
          "camtracetest1": {
            "type": "string"
      },
          "camtracetest2": {
          "type": "string"
      }
    },
  },
    "description": "An object describing names of possible parameters of each event handled by the connector"
  }
},
  "required": [
    "labels",
    "descriptions",
    "params"
  ]
}

Get event details

Get event details
GET/events

This method must return an HTML page containing information about the event requested.

The page is embedded into the CamTrace client when a user is requesting details about an event that occurred. You are free to choose what elements to display and how to display them.

If you want to include static ressources files (images, css, javascript files, …) in your HTML page, they must be placed behind the /static path. All files and folders behind this path have to be reachable without authentication.

Example URI

GET /api/v1/events
URI Parameters
HideShow
eventid
string (required) Example: 7ee96ce3-a311-4f14-a22f-a7e20cea2170

UUID V4 of the event requested

Response  200
HideShow
Headers
Content-Type: text/html
Body
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="static/bootstrap.min.css">
    </head>
    <body>
        Event of type <b>external.camtracetest1</b> occurred at 15:49:31
    </body>
</html>

Create events report

Create events report
POST/events

This method must return an HTML page containing informations about the events requested.

The page is embedded into the CamTrace client or transformed into a PDF document when a user is requesting informations about an events list that occurred. You are free to choose what informations to display and how to display them.

If you want to include static ressources files (images, css, javascript files, …) in your HTML page, they must be placed behind the /static path. All files and folders behind this path have to be reachable without authentication.

Example URI

POST /api/v1/events
Request
HideShow
Headers
Content-Type: application/json
Body
{
  "ids": [
    "eee2e165-688d-4b13-9e97-670dd1c08e21",
    "31cadd2d-1051-4f78-beda-b73b3918f722"
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "ids": {
      "type": "array",
      "description": "Array containing list of event ids",
      "items": {
        "type": "UUIDv4"
      }
    },
  },
  "required": [
    "ids"
  ]
}
Response  200
HideShow
Headers
Content-Type: text/html
Body
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="static/bootstrap.min.css">
    </head>
    <body>
        Event of type <b>external.camtracetest1</b> occurred at 15:49:31
        <hr>
        Event of type <b>external.camtracetest1</b> occurred at 15:50:07
    </body>
</html>

Notify event

Notify event
WS SEND{json-event}

Your connector websocket server must have accepted and kept alive the CT-Server connection

When new events are created/recevied by your connector, it must notify the CamTrace server that a new event occured by send the event json parameters to the CT-Server.

Your connector websocket server adress has been proviously sent to the CT-SERVER via the configuration route.

Example of json event

WS SEND {"eventId":"68017368-37b2-4698-9ac3-12cbb9a51ecf","type":"'external.camtracetest1","timestamp":"2022-07-15T14:48:00.000Z","description":{"customParams":{"demoParam":1}}}
Json Event  
HideShow
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
      "properties": {
        "eventId": {
          "type": "string",
          "description": "UUID v4 of the event"
        },
        "type": {
          "type": "string",
          "description": "Type of the event"
        },
        "timestamp": {
          "type": "string",
          "description": "Timestamp of the event"
        },
        "description": {
          "type": "object",
          "properties": {
            "args": {
              "type": "object",
              "description": "Object containing the event arguments"
            }
          }
      },
      "required": [
        "eventId",
        "type",
        "timestamp"
      ]
  },

}
Response  None

Purge events

Purge events
POST/events/purge

This route is optionnal

The CamTrace server has a mechanism to automatically purge events older than "DBP" days (30 days by default). This parameter is configurable during the connector registration in CT-Server admin.

When this mechanism is triggered, the server calls this route to inform that it purged all events occurred before purgeBefore.

The purgeBefore argument is a string formatted in ISO 8601.

Example URI

POST /api/v1/events/purge
Request
HideShow
Headers
Content-Type: application/json
Body
{
  "purgeBefore": "2022-05-27T00:00:00.000000Z"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "purgeBefore": {
      "type": "string"
    }
  },
  "required": [
    "purgeBefore"
  ]
}
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "totalPurged": 1
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "totalPurged": {
      "type": "number",
      "description": "The number of purged events"
    }
  }
}

Searching

Theses routes are used by the CamTrace client for querying events matching one or several criteria.

Get events criteria
GET/events/search/criteria

This route returns a list of criteria. A criterion is an event property on which a filter can be applied. The JSON schema below explains what properties and how the criteria must be returned in your connector response. We advise that you include at least a timestamp criteria for searching events by date and a type criteria if you manage several different types in your connector. Other specific search event parameters criteria names may be prefixed with external.

Example URI

GET /api/v1/events/search/criteria
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "criteria": [
    {
      "name": "type",
      "description": "Event type",
      "format": "enum",
      "values": [
        "external.camtracetest1",
        "external.camtracetest2"
      ],
      "texts": [
        "Event test 1",
        "Event test 2"
      ]
    },
    {
      "name": "timestamp",
      "description": "Event date",
      "format": "datetime"
    },
    {
      "name": "external.demoParam",
      "description": "Demo parameter",
      "format": "integer"
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "criteria": {
      "type": "array",
      "description": "Array containing list of criteria",
      "items": {
        "type": "object",
        "description": "A criteria object",
        "properties": {
          "name": {
            "type": "string",
            "description": "The name of the event property"
          },
          "description": {
            "type": "string",
            "description": "A string describing the event property"
          },
          "format": {
            "type": "string",
            "description": "Value format",
            "enum": [
              "string",
              "integer",
              "datetime",
              "boolean"
            ]
          },
          "values": {
            "type": "array",
            "description": "Array of string containing all valid values when the format is enum",
            "items": {
              "type": "string"
            }
          },
          "texts": {
            "type": "array",
            "description": "Array of string containing labels for valid values when the format is enum",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "name",
          "description",
          "format"
        ]
      }
    }
  },
  "required": [
    "criteria"
  ]
}

Search event
POST/events/search

This route allows to perform a search with specified criteria. It returns the event list matching the criteria and the result’s pagination information.

Events order may be requested by client, setting request parameter descOrder. If true, events must be sorted by date in descending order (more recent to less recent). If the parameter is false or not specified, events must be sorted by date in ascending order in your response.

Example URI

POST /api/v1/events/search
Request
HideShow
Headers
Content-Type: application/json
Body
{
  "criteria": [
    {
      "name": "type",
      "value": "external.camtracetest1",
      "comparator": "="
    }
  ],
  "paging": {
    "offset": 0,
    "limit": 25
  }
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "criteria": {
      "type": "array",
      "description": "Array containing list of criteria",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": " Name of the event property to filter on"
          },
          "value": {
            "type": "string",
            "description": "Value of the event property to filter on"
          },
          "comparator": {
            "type": "string",
            "description": "Comparator. If omitted it will be assumed as '='",
            "enum": [
              "!=",
              "=",
              ">=",
              ">",
              "<=",
              "<",
              "LIKE"
            ]
          }
        },
        "required": [
          "name",
          "value"
        ]
      }
    },
    "paging": {
      "type": "object",
      "description": "Pagination parameters",
      "properties": {
        "offset": {
          "type": "number",
          "description": "Offset from the beginning of the resultset"
        },
        "limit": {
          "type": "number",
          "description": "Result limit"
        }
      }
    }
  },
  "required": [
    "criteria"
  ]
}
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "paging": {
    "next": {
      "offset": 25,
      "limit": 25
    }
  },
  "total": 197,
  "events": [
    {
      "id": "68017368-37b2-4698-9ac3-12cbb9a51ecf",
      "type": "external.camtracetest1",
      "timestamp": "2022-07-15T14:48:00.000Z",
      "description": {
          "customParams": {
              "demoParam": 1
        },
      },
      "label": "CamTrace event test with param 1"
    }
  ]
}
Schema
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "properties": {
        "paging": {
            "type": "object",
            "description": "Pagination parameters"
            "properties": {
                "next": {
                    "type": "object",
                    "description": "Object containing parameters for the next resultset"
                    "properties": {
                        "offset": {
                            "type": "integer",
                            "description": "Offset parameter for the next resultset"
                        },
                        "limit": {
                            "type": "integer"
                            "description": "Limit parameter for the next resultset"
                        }
                    },
                    "required": [
                        "offset",
                        "limit"
                    ]
                }
            },
            "required": [
                "next"
            ]
        },
        "total": {
          "type": "integer",
          "description": "Total number of searched events",
          "required": [
              "total"
          ]
      },
      "events": {
          "type": "array",
          "description": "List of events matching the specified criteria"
          "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "UUIDv4",
                  "description": "Event id"
              },
                  "type": {
                      "type": "string",
                      "description": "Event type"
                  },
                  "timestamp": {
                      "type": "date",
                      "description": "Datetime of the event creation, formatted in ISO 8601"
                  },
                  "description": {
                    "type": "object",
                    "description": "Event JSON description details"
                },
                  "label": {
                      "type": "string",
                      "description": "Textual description of the event with dynamic params already included (no JSON pointers)"
                  }
              }
          }
      }
    },
    "required": [
        "events"
    ]
}

Generated by aglio on 14 March 2023