Ontology
Query Ontology
Execute SPARQL queries against the JARVIS knowledge graph to retrieve entities, relationships, and metadata extracted from financial events.
POST /ontology/query
| Parameter | Type | DataType | Description |
|---|---|---|---|
| query | body | string | SPARQL query to execute (required) |
| timeout | body | integer | Query timeout in seconds, max 30 (optional, default: 30) |
| include_raw | body | boolean | Include raw Neptune response alongside formatted results (optional, default: false) |
The request body must be JSON with at least the query field. Standard prefixes (rdf:, rdfs:, xsd:, aiera:) are auto-injected if used but not declared.
Request
POST https://premium.aiera.com/api/ontology/query
Content-Type: application/json
{
"query": "SELECT ?org ?label WHERE { ?org rdf:type aiera:ORGANIZATION . ?org rdfs:label ?label } LIMIT 10"
}
Response
Responses follow the SPARQL 1.1 Results JSON Format conventions, wrapped in a standardized envelope.
Success Response
{
"success": true,
"data": {
"variables": ["org", "label"],
"bindings": [
{
"org": {
"value": "http://aiera.com/ontology#Apple_Inc",
"type": "uri"
},
"label": {
"value": "Apple Inc",
"type": "literal"
}
},
{
"org": {
"value": "http://aiera.com/ontology#Microsoft_Corp",
"type": "uri"
},
"label": {
"value": "Microsoft Corp",
"type": "literal"
}
}
]
},
"metadata": {
"query_type": "SELECT",
"execution_time_ms": 150,
"result_count": 2,
"truncated": false,
"limit_applied": null
}
}
Response Fields
Top Level
| Field | Type | Description |
|---|---|---|
success | boolean | Whether the query executed successfully |
data | object | Query results (format varies by query type) |
metadata | object | Execution metadata |
Data Object (SELECT queries)
| Field | Type | Description |
|---|---|---|
variables | string[] | Variable names from the SELECT clause |
bindings | object[] | Array of result rows, each containing variable-to-value maps |
Binding Value Object
Each binding value follows the SPARQL JSON Results specification:
| Field | Type | Description |
|---|---|---|
value | string | The actual value -- a URI string or literal value |
type | string | One of: uri, literal, bnode (blank node) |
datatype | string | (Optional) XSD datatype for typed literals, e.g. http://www.w3.org/2001/XMLSchema#integer |
lang | string | (Optional) Language tag for language-tagged strings, e.g. en |
Metadata Object
| Field | Type | Description |
|---|---|---|
query_type | string | Type of query executed (SELECT, ASK, etc.) |
execution_time_ms | integer | Query execution time in milliseconds |
result_count | integer | Number of results returned |
truncated | boolean | Whether results were truncated (max 10,000) |
limit_applied | integer | The limit that was applied, if any |
ASK Query Response
ASK queries return a boolean indicating whether a pattern exists:
{
"success": true,
"data": {
"boolean": true
},
"metadata": {
"query_type": "ASK",
"execution_time_ms": 45,
"result_count": 1,
"truncated": false
}
}
Error Response
{
"success": false,
"error": {
"code": "QUERY_SYNTAX_ERROR",
"message": "Unable to determine query type",
"details": "Query must start with SELECT, ASK, CONSTRUCT, or DESCRIBE"
}
}
Error Codes
| Code | HTTP Status | Description |
|---|---|---|
INVALID_REQUEST | 400 | Missing query field or malformed JSON |
QUERY_SYNTAX_ERROR | 400 | Invalid SPARQL syntax |
QUERY_TIMEOUT | 504 | Query exceeded timeout limit |
QUERY_EXECUTION_ERROR | 502 | Neptune returned an error |
NEPTUNE_CONNECTION_ERROR | 502 | Cannot reach Neptune |
FORBIDDEN_OPERATION | 403 | UPDATE queries are blocked |
INTERNAL_ERROR | 500 | Unexpected server error |
Query Examples
List Organizations
{
"query": "SELECT ?org ?label WHERE { ?org rdf:type aiera:ORGANIZATION . OPTIONAL { ?org rdfs:label ?label } } ORDER BY ?label LIMIT 100"
}
Find People with Roles
{
"query": "SELECT ?name ?role ?company WHERE { ?person rdf:type aiera:PERSON . ?person rdfs:label ?name . OPTIONAL { ?person aiera:role ?role } OPTIONAL { ?person aiera:works_for ?org . ?org rdfs:label ?company } } ORDER BY ?company ?name LIMIT 100"
}
Search by Label (Case-Insensitive)
{
"query": "SELECT ?entity ?label WHERE { ?entity rdfs:label ?label . FILTER(CONTAINS(LCASE(?label), \"apple\")) } LIMIT 20"
}
Find Competitive Relationships
{
"query": "SELECT ?company1 ?company2 WHERE { ?org1 aiera:competes_with ?org2 . ?org1 rdfs:label ?company1 . ?org2 rdfs:label ?company2 }"
}
Entity Type Counts
{
"query": "SELECT ?type (COUNT(?entity) AS ?count) WHERE { ?entity rdf:type ?type } GROUP BY ?type ORDER BY DESC(?count)"
}
Check if Entity Exists (ASK)
{
"query": "ASK WHERE { ?entity rdfs:label \"Apple Inc\" . ?entity rdf:type aiera:ORGANIZATION }"
}
Query a Specific Event's Data
Data is organized into named graphs by event ID:
{
"query": "SELECT ?entity ?type ?label WHERE { GRAPH aiera:event/12345 { ?entity rdf:type ?type . OPTIONAL { ?entity rdfs:label ?label } } FILTER(STRSTARTS(STR(?type), \"http://aiera.com/ontology#\")) }"
}
High-Confidence Relationships (Reified Statements)
Relationships include metadata via RDF reification:
{
"query": "SELECT ?company1Label ?company2Label ?confidence WHERE { ?stmt rdf:type rdf:Statement ; rdf:subject ?company1 ; rdf:predicate aiera:competes_with ; rdf:object ?company2 ; aiera:confidence ?confidence . ?company1 rdfs:label ?company1Label . ?company2 rdfs:label ?company2Label . FILTER(?confidence >= 0.8) } ORDER BY DESC(?confidence)",
"timeout": 15
}
All Connections for an Entity
{
"query": "SELECT ?predicate ?relatedLabel ?direction WHERE { { ?entity rdfs:label \"Apple Inc\" . ?entity ?predicate ?related . ?related rdfs:label ?relatedLabel . BIND(\"outgoing\" AS ?direction) } UNION { ?entity rdfs:label \"Apple Inc\" . ?related ?predicate ?entity . ?related rdfs:label ?relatedLabel . BIND(\"incoming\" AS ?direction) } FILTER(?predicate != rdf:type) FILTER(STRSTARTS(STR(?predicate), \"http://aiera.com/ontology#\")) }"
}
Code Samples
Bash
curl --request POST \
--url 'https://premium.aiera.com/api/ontology/query' \
--header 'X-API-Key: your-rest-api-key' \
--header 'Content-Type: application/json' \
--data '{
"query": "SELECT ?org ?label WHERE { ?org rdf:type aiera:ORGANIZATION . ?org rdfs:label ?label } LIMIT 10"
}'
Python
import requests
response = requests.post(
"https://premium.aiera.com/api/ontology/query",
headers={
"X-API-Key": "your-rest-api-key",
"Content-Type": "application/json",
},
json={
"query": """
SELECT ?org ?label
WHERE {
?org rdf:type aiera:ORGANIZATION .
?org rdfs:label ?label .
}
LIMIT 10
""",
"timeout": 15,
},
)
result = response.json()
if result["success"]:
print(f"Found {result['metadata']['result_count']} results")
print(f"Query took {result['metadata']['execution_time_ms']}ms")
for binding in result["data"]["bindings"]:
label = binding["label"]["value"]
uri = binding["org"]["value"]
print(f" - {label} ({uri})")
else:
print(f"Error: {result['error']['message']}")