Synapse HTTP/REST API

Many components within the Synapse ecosystem provide HTTP/REST APIs to provide a portable interface. Some of these APIs are RESTful, while other (streaming data) APIs are technically not.

HTTP/REST API Conventions

All Synapse RESTful APIs use HTTP GET/POST methods to retrieve and modify data. All POST requests expect a JSON body. Each RESTful API call will return a result wrapper dictionary with one of two conventions.

For a successful API call:

{"status": "ok", "result": "some api result here"}

or for an unsuccessful API call:

{"status": "err": "code": "ErrCodeString", "mesg": "A human friendly message."}

Streaming HTTP API endpoints, such as the interface provided to retrieve nodes from a Synapse Cortex, provide JSON results via HTTP chunked encoding where each chunk is a single result.

Client example code in these docs uses the python “aiohttp” module and assumes familiarity with python asynchronous code conventions. However, they should be enough to understand the APIs basic operation.

Authentication

While not in “insecure” mode, most Synapse HTTP APIs require an authenticated user. HTTP API endpoints requiring authentication may be accessed using either HTTP Basic authentication via the HTTP “Authorization” header or as part of an authenticated session. For more information on configuring users/roles see TODO.

To create and use an authenticated session, the HTTP client library must support cookies.

/api/v1/login

The login API endpoint may be used to create an authenticated session. This session may then be used to call other HTTP API endpoints as the authenticated user.

import aiohttp

async def logInExample(ssl=False):

    async with aiohttp.ClientSession() as sess:

        info = {'user': 'visi', 'passwd': 'secret'}
        async with sess.post(f'https://localhost:56443/api/v1/login', json=info, ssl=ssl) as resp:
            item = await resp.json()
            if item.get('status') != 'ok':
                code = item.get('code')
                mesg = item.get('mesg')
                raise Exception(f'Login error ({code}): {mesg}')

            # we are now clear to make additional HTTP API calls using sess

/api/v1/auth/users

Method

GET

Returns
A list of dictionaries, each of which represents a user on the system.

/api/v1/auth/roles

Method

GET

Returns
A list of dictionaries, each of which represents a role on the system.

/api/v1/auth/adduser

Method

POST

This API endpoint allows the caller to add a user to the system.

Input

This API expects the following JSON body:

{ "name": "myuser" }

Any additional “user dictionary” fields (other than “iden”) may be specified.

Returns
The newly created role dictionary.

/api/v1/auth/addrole

Method

POST

This API endpoint allows the caller to add a role to the system.

Input

This API expects the following JSON body:

{ "name": "myrole" }

Any additional “role dictionary” fields (other than “iden”) may be specified.

Returns
The newly created role dictionary.

/api/v1/auth/delrole

Method

POST

This API endpoint allows the caller to delete a role from the system.

Input

This API expects the following JSON body:

{ "name": "myrole" }
Returns
null

/api/v1/auth/user/<id>

Method

POST

This API allows the caller to modify specified elements of a user dictionary.

Input
This API expects a JSON dictionary containing any updated values for the user.
Returns
The updated user dictionary.
Method

GET

This API allows the caller to retrieve a user dictionary.

Returns
A user dictionary.

/api/v1/auth/password/<id>

Method

POST

This API allows the caller to change a users password. The authenticated user must either be an admin or the user whose password is being changed.

Input
This API expects a JSON dictionary containing the a key passwd with the new password string.
Returns
The updated user dictionary.

/api/v1/auth/role/<id>

Method

POST

This API allows the caller to modify specified elements of a role dictionary.

Input
This API expects a dictionary containing any updated values for the role.
Returns
The updated role dictionary.
Method

GET

This API allows the caller to retrieve a user dictionary.

Returns
A user dictionary.

/api/v1/auth/grant

Method

POST

This API allows the caller to grant a role to a given user.

Input

This API expects the following JSON body:

{
    "user": "<id>",
    "role": "<id>"
}
Returns
The updated user dictionary.

/api/v1/auth/revoke

Method

POST

This API allows the caller to revoke a role which was previously granted to a user.

Input

This API expects the following JSON body:

{
    "user": "<id>",
    "role": "<id>"
}
Returns
The updated user dictionary.

Cortex

A Synapse Cortex implements an HTTP API for interacting with the hypergraph and data model. Some of the provided APIs are pure REST APIs for simple data model operations and single/simple node modification. However, many of the HTTP APIs provided by the Cortex are streaming APIs which use HTTP chunked encoding to deliver a stream of results as they become available.

/api/v1/feed

The Cortex feed API endpoint allows the caller to add nodes in bulk.

Method

POST

Input
The API expects the following JSON body::
{
“items”: [ <node>, … ], # and optionally… “view”: <iden>,

}

Each <node> is expected to be in packed tuple form::
[ [<formname>, <formvalu>], {…} ]
Returns
The API returns {"status": "ok", "result": null} on success and any failures are returned using the previously mentioned REST API convention.

/api/v1/storm

The Storm API endpoint allows the caller to execute a Storm query on the Cortex and stream back the messages generated during the Storm runtime execution. In addition to returning nodes, these messsages include events for node edits, tool console output, etc.

Method

GET

Input

The API expects the following JSON body:

{
    "query": "a storm query here",

    # optionally...

    "opts": {
        "repr": <bool>,         # Add optional "reprs" field to returned nodes.
        "limit": <int>,         # Limit the total number of nodes to be returned.
        "vars": {
            <name>: <value>,    # Variables to map into the Storm query runtime.
        },
        "ndefs": [],            # A list of [form, valu] tuples to use as initial input.
        "idens": [],            # A list of node iden hashes to use as initial input.
        "scrub": {}             # Rules for which tags should be included/excluded in output.
    }
}
Returns

The API returns a series of messages generated by the Storm runtime. Each message is returned as an HTTP chunk, alling readers to consume the resulting nodes as a stream.

Each message has the following basic structure:

[ "type", { ..type specific info... } ]

One particularly useful option that can be included in the request is a set of scrub rules. These rules describe what data should be included/excluded from the nodes that are returned. Currently the only rule type supported is include for tags. An example scrub rule to only include specific tags in the result output would look like:

"scrub": {
    "include": {
        "tags": [
            "cno",
            "rep.vt"
        ]
    }
}

This would cause tags besides cno, rep.vt and any children of those tags to be stripped from the resulting nodes before they are returned.

/api/v1/storm/nodes

The Storm nodes API endpoint allows the caller to execute a Storm query on the Cortex and stream back the resulting nodes. This streaming API has back-pressure, and will handle streaming millions of results as the reader consumes them.

Method

GET

Input
See /api/v1/storm for expected JSON body input.
Returns

The API returns the resulting nodes from the input Storm query. Each node is returned as an HTTP chunk, allowing readers to consume the resulting nodes as a stream.

Each serialized node will have the following structure:

[
    [<form>, <valu>],       # The [ typename, typevalue ] definition of the node.
    {
        "iden": <hash>,     # A stable identifier for the node.
        "tags": {},         # The tags on the node.
        "props": {},        # The node's secondary properties.

        # optionally (if query opts included {"repr": True}
        "reprs": {}         # Presentation values for props which need it.
    }
]

/api/v1/storm/export

The Storm export API endpoint allows the caller to execute a Storm query on the Cortex and export the resulting nodes in msgpack format such that they can be directly ingested with the syn.nodes feed function.

Method

GET

Input
See /api/v1/storm for expected JSON body input.
Returns

The API returns the resulting nodes from the input Storm query. This API yields nodes after an initial complete lift in order to limit exported edges.

Each exported node will be in msgpack format.

/api/v1/model

Method

GET

This API allows the caller to retrieve the current Cortex data model.

Input
The API takes no input.
Returns

The API returns the model in a dictionary, including the types, forms and tagprops. Secondary property information is also included for each form:

{
    "types": {
        ...  # dictionary of type definitions
    },
    "forms": {
        ...  # dictionary of form definitions, including secondary properties
    },
    "tagprops": {
        ...  # dictionary of tag property definitions
    }
}

/api/v1/model/norm

Method

GET, POST

This API allows the caller to normalize a value based on the Cortex data model. This may be called via a GET or POST requests.

Input

The API expects the following JSON body:

{
    "prop": "prop:name:here",
    "value": <value>,
}
Returns

The API returns the normalized value as well as any parsed subfields or type specific info:

{
    "norm": <value>,
    "info": {
        "subs": {},
        ...
    }
}

/api/v1/storm/vars/get

Method

GET

This API allows the caller to retrieve a storm global variable.

Input

The API expects the following JSON body:

{
    "name": "varnamehere",
    "default": null,
}
Returns
The API returns the global variable value or the specified default using the REST API convention described earlier.

/api/v1/storm/vars/set

Method

POST

This API allows the caller to set a storm global variable.

Input

The API expects the following JSON body:

{
    "name": "varnamehere",
    "value": <value>,
}
Returns
The API returns true using using the REST API convention described earlier.

/api/v1/storm/vars/pop

Method

POST

This API allows the caller to pop/delete a storm global variable.

Input

The API expects the following JSON body:

{
    "name": "varnamehere",
    "default": <value>,
}
Returns
The API returns the the current value of the variable or default using using the REST API convention described earlier.

/api/v1/core/info

Method

GET

This API allows the caller to retrieve the current Cortex version, data model definitions, and Storm information.

Input
The API takes no input.
Returns

The API returns the model in a dictionary, including the types, forms and tagprops. Secondary property information is also included for each form:

{
    "version": [ <major>, <minor>, <patch> ], # Version tuple
    "modeldict": {
        ...  # dictionary of model definitions
    },
    "stormdocs": {
        "libraries": [
            ... # list of information about Storm libraries.
        ],
        "types": [
            ... # list of information about Storm types.
        ]
    }
}

Axon

A Synapse Axon implements an HTTP API for uploading and downloading files. The HTTP APIs use HTTP chunked encoding for handling large files.

/api/v1/axon/files/del

This API allows the caller to delete multiple files from the Axon by the SHA-256.

Method

POST

Input

The API expects the following JSON body:

{
    "sha256s": [<sha256>, ...],
}
Returns
The API returns an array of SHA-256 and boolean values representing whether each was found in the Axon and deleted. The array is returned using using the REST API convention described earlier.

/api/v1/axon/files/put

This API allows the caller to upload and save a file to the Axon. This may be called via a PUT or POST request.

Method

PUT, POST

Input
The API expects a stream of byte chunks.
Returns

On successful upload, or if the file already existed, the API returns information about the file:

{
  "md5": "<the md5sum value of the uploaded bytes>",
  "sha1": "<the sha1 value of the uploaded bytes>",
  "sha256": "<the sha256 value of the uploaded bytes>",
  "sha512": "<the sha512 value of the uploaded bytes>",
  "size": <the size of the uploaded bytes>
}

/api/v1/axon/files/has/sha256/<SHA-256>

This API allows the caller to check if a file exists in the Axon as identified by the SHA-256.

Method

GET

Returns
True if the file exists; False if the file does not exist.

/api/v1/axon/files/by/sha256/<SHA-256>

This API allows the caller to retrieve or remove a file from the Axon as identified by the SHA-256. If the file does not exist a 404 will be returned.

Method

GET

Returns
If the file exists a stream of byte chunks will be returned to the caller.
Method

DELETE

Returns
Boolean via the REST API convention described earlier. If the file is not found an error is returned.