HTTP/REST API
The Synapse UI has a number of HTTP/REST APIs that can be used by external clients.
HTTP/REST API Conventions
The UI follows the same HTTP/REST conventions as Synapse.
Authentication
/api/v1/optic/login
The login API endpoint to get an UI session. Unless an alternative authentication scheme has been configured this endpoint will behave identically to the Cortex endpoint. Details for default login endpoint behavior can be found here.
Note
When Azure AD Authentication is configured the POST body JSON object should contain a token property with the
access token retrieved from Azure AD.
Warning
When SAML SSO Authentication is configured, this API cannot be used to get an API session token.
Cortex
/api/v1/storm
Storm API endpoint that behaves identically to the Cortex endpoint. To access this endpoint, the caller must present
either a valid sess cookie obtained from the /api/v1/optic/login API endpoint or an API key. Additional details
for this endpoint can be found here.
/api/v1/storm/call
Storm call API endpoint that behaves identically to the Cortex endpoint. To access this endpoint, the caller must
present either a valid sess cookie obtained from the /api/v1/optic/login API endpoint or an API key. Additional
details for this endpoint can be found
here.
/api/v1/storm/export
Storm export API endpoint that behaves identically to the Cortex endpoint. To access this endpoint, the caller must
present either a valid sess cookie obtained from the /api/v1/optic/login API endpoint or an API key. Additional
details for this endpoint can be found
here.
/api/v1/mcp
Note
The MCP endpoint is currently considered beta and is subject to change.
This endpoint implements a Model Context Protocol (MCP) server over the MCP Streamable HTTP transport. It exposes the Cortex to MCP capable clients (such as LLM agents) as a set of tools and resources for running and validating Storm queries, browsing the Synapse data model, and managing views.
To access this endpoint, it is easiest to use an API key. Additional details and MCP setup instructions for this endpoint can be found here.
/api/ext
Extended HTTP API endpoint that behaves identically the Cortex endpoint. If the endpoint is authenticated, the caller
must present a valid sess cookie obtained from the /api/v1/optic/login API endpoint or an API key. Additional
details for this endpoint can be found
here
Examples
The following examples show the use of the Python aiohttp and requests libraries to interact with the Optic HTTP
API endpoints. These show us logging into the login endpoint and using the Storm endpoints.
aiohttp
This example uses asynchronous Python programming and the aiohttp library.
import sys
import json
import pprint
import asyncio
import aiohttp
# Examples for using the Synapse UI HTTP API to call Storm queries.
# For more information about these APIs, refer to the following documentation.
# https://synapse.docs.vertex.link/projects/optic/en/latest/user_interface/httpapi.html
# https://synapse.docs.vertex.link/en/latest/synapse/httpapi.html
# https://synapse.docs.vertex.link/en/latest/synapse/devguides/storm_api.html
# Fill in your url, user, and password.
base_url = 'https://youroptic.yourdomain.com'
username = 'XXXX'
password = 'XXXX'
async def main(argv):
async with aiohttp.ClientSession() as sess:
# Login to setup a session cookie with the UI. This sets the sess cookie.
# aiohttp.ClientSession automatically handles the Set-Cookie header to
# store and reuse the session cookie. Refer to the documentation for
# other HTTPAPI clients and tools for how they handle cookies.
url = f'{base_url}/api/v1/optic/login'
data = {'user': username, 'passwd': password}
async with await sess.post(url, json=data) as resp:
assert resp.status == 200, f'Failed to login resp.status={resp.status}'
print(resp.headers)
# api/v1/storm - This streams Storm messages back to the user,
# much like the telepath storm() API. The example shows some
# node and print messages being sent back.
query = '.created $lib.print($node.repr(".created")) | limit 3'
data = {'query': query, 'opts': {'repr': True}}
url = f'{base_url}/api/v1/storm'
async with sess.get(url, json=data) as resp:
async for byts, x in resp.content.iter_chunks():
if not byts:
break
mesg = json.loads(byts)
pprint.pprint(mesg)
# storm/call - this is intended for use with the Storm return() syntax
# as they return a singular value, instead of a stream of messages.
query = '$foo = $lib.str.format("hello {valu}", valu="world") return ($foo)'
data = {'query': query}
url = f'{base_url}/api/v1/storm/call'
async with sess.get(url, json=data) as resp:
info = await resp.json()
pprint.pprint(info)
if __name__ == '__main__':
sys.exit(asyncio.run(main(sys.argv[1:])))
requests
This example uses Python programming and the requests library.
import sys
import json
import pprint
import requests
# Examples for using the Synapse UI HTTP API to call Storm queries.
# For more information about these APIs, refer to the following documentation.
# https://synapse.docs.vertex.link/projects/optic/en/latest/user_interface/httpapi.html
# https://synapse.docs.vertex.link/en/latest/synapse/httpapi.html
# https://synapse.docs.vertex.link/en/latest/synapse/devguides/storm_api.html
# Fill in your url, user, and password.
base_url = 'https://youroptic.yourdomain.com'
username = 'XXXX'
password = 'XXXX'
def main(argv):
sess = requests.session()
# Login to setup a session cookie with the UI. This sets the sess cookie.
# requests.session automatically handles the Set-Cookie header to
# store and reuse the session cookie. Refer to the documentation for
# other HTTPAPI clients and tools for how they handle cookies.
url = f'{base_url}/api/v1/optic/login'
data = {'user': username, 'passwd': password}
resp = sess.post(url, json=data)
assert resp.status_code == 200, f'Failed to login resp.status={resp.status}'
# api/v1/storm - This streams Storm messages back to the user,
# much like the telepath storm() API. The example shows some
# node and print messages being sent back.
query = '.created $lib.print($node.repr(".created")) | limit 3'
data = {'query': query, 'opts': {'repr': True}}
url = f'{base_url}/api/v1/storm'
resp = sess.get(url, json=data, stream=True)
for chunk in resp.iter_content(chunk_size=None, decode_unicode=True):
mesg = json.loads(chunk)
pprint.pprint(mesg)
# storm/call - this is intended for use with the Storm return() syntax
# as they return a singular value, instead of a stream of messages.
query = '$foo = $lib.str.format("hello {valu}", valu="world") return ($foo)'
data = {'query': query}
url = f'{base_url}/api/v1/storm/call'
resp = sess.get(url, json=data)
info = resp.json()
pprint.pprint(info)
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))