Skip to content

Latest commit

 

History

History
505 lines (406 loc) · 9.99 KB

File metadata and controls

505 lines (406 loc) · 9.99 KB

Morpheus HTTP API

Base URL: http://127.0.0.1:8080 (default)

Environment:

  • MORPHEUS_HTTP_ADDR: bind address (default 127.0.0.1:8080)
  • MORPHEUS_HTTP_ADMIN_TOKEN: when set, admin endpoints require Authorization: Bearer <token>
  • MORPHEUS_HTTP_CORS=permissive: enable permissive CORS

Response and Errors

Success response:

{ "data": { ... } }

Error response:

{ "code": "...", "message": "..." }

ID Format

Cell, vertex, edge IDs are base58-encoded 16-byte IDs. The server returns base58 strings for IDs.

Data Encoding

Graph vertex data and edge body use JSON objects (maps). Cell data accepts a generic HttpValue.

Map

{ "k": "v" }

Array

[1, 2, 3]

Typed Values

Use {"$type": "...", "value": ...} for non-JSON or specific types.

Examples:

{"$type":"u64","value":123}
{"$type":"id","value":"5QqkMJFr5s7J9wB8Q2kN1J"}
{"$type":"bytes","value":[1,2,3]}
{"$type":"u32[]","value":[1,2,3]}

Supported $type values:

  • i8, i16, i32, i64, u8, u16, u32, u64, f32, f64
  • char, string, bool, na
  • id (base58 string value)
  • bytes, small_bytes (array of byte numbers)
  • map, array
  • bool[], char[], i8[], i16[], i32[], i64[], u8[], u16[], u32[], u64[], f32[], f64[], pos2d32[], pos2d64[], pos3d32[], pos3d64[], id[], string[], bytes[], small_bytes[]

Notes:

  • Untagged numbers are interpreted as i64, u64, or f64 depending on JSON parsing.
  • id decoding also accepts { "higher": <u64>, "lower": <u64> } for backward compatibility, but responses return base58 strings.

Health

GET /v1/health

Response:

{ "data": {} }

Admin Maintenance

POST /v1/admin/nuke (admin)

  • Removes all in-memory data cells across schemas.
  • For vertex schemas, removal is performed through graph vertex deletion first (so edge lists are updated correctly).
  • Graph edge and non-graph cells are then removed by cell id.
  • Schemas are not deleted (removed_schemas is currently always 0).

Response:

{
  "data": {
    "scanned_schemas": 12,
    "removed_vertices": 120,
    "removed_cells": 842,
    "removed_schemas": 0,
    "cleared_cell_index_entries": 962
  }
}

POST /v1/admin/nuke/schema (admin)

  • Removes non-system schemas.
  • Keeps internal/system schemas to avoid runtime breakage (for example names prefixed with _, HNSW, INDEX, INVERTED, RANGED).

Response:

{
  "data": {
    "scanned_schemas": 12,
    "removed_schemas": 5,
    "skipped_schemas": 7
  }
}

Graph Schemas (Morpheus)

GET /v1/graph/schemas

GET /v1/graph/schemas/:name

POST /v1/graph/schemas (admin)

Request:

{
  "id": 0,
  "name": "my_vertex",
  "schema_type": "Vertex",
  "key_field": null,
  "fields": [],
  "is_dynamic": true
}

Edge schema example:

{
  "name": "my_edge",
  "schema_type": {
    "Edge": {
      "edge_type": "Directed",
      "has_body": true
    }
  },
  "fields": [],
  "is_dynamic": true
}

DELETE /v1/graph/schemas/:name (admin)

Cell Schemas (Neb)

GET /v1/cell/schemas

GET /v1/cell/schemas/:name

POST /v1/cell/schemas (admin)

Request:

{
  "id": 0,
  "name": "my_cell",
  "key_field": null,
  "fields": [],
  "is_dynamic": true,
  "is_scannable": false
}

DELETE /v1/cell/schemas/:name (admin)

Graph Operations

POST /v1/graph/vertices (admin)

Request by schema name:

{
  "schema_name": "my_vertex",
  "data": {}
}

Request by schema id:

{
  "schema_id": 42,
  "data": {},
  "id": "5QqkMJFr5s7J9wB8Q2kN1J"
}

GET /v1/graph/vertices/:id

DELETE /v1/graph/vertices/:id (admin)

PATCH /v1/graph/vertices/:id (admin)

Request:

{
  "data": {
    "nickname": "alice",
    "score": {"$type": "u64", "value": 42}
  }
}

POST /v1/graph/edges (admin)

Request:

{
  "from_id": "5QqkMJFr5s7J9wB8Q2kN1J",
  "to_id": "3Yv8v4Cw1W5Hk9p2LxQw9Q",
  "schema_name": "my_edge",
  "body": {}
}

DELETE /v1/graph/edges (admin)

Request:

{
  "from_id": "5QqkMJFr5s7J9wB8Q2kN1J",
  "to_id": "3Yv8v4Cw1W5Hk9p2LxQw9Q",
  "schema_name": "my_edge",
  "cell_id": "2m8JqZfC2MbgQfE7x4oP6R"
}
  • cell_id is optional. If multiple edges match from_id + to_id + schema, provide cell_id to disambiguate.

DELETE /v1/graph/edges/:id (admin)

  • Deletes an edge by edge cell id (base58).
  • This removes both the edge cell and edge-list references from both endpoint vertices.

GET /v1/graph/vertices/:id/edges?schema=<name-or-id>&direction=outbound|inbound|undirected

Query Operations

POST /v1/query

Request:

{
  "schema_name": "my_vertex",
  "selection": "(and (= score 1u64) (>= rank 10u64))",
  "ordering": "forward",
  "order_by_field": "score",
  "limit": 50,
  "offset": 0
}
  • selection must be a single Neb Lisp expression.
  • selection should use schema field names directly (for example score, rank).
  • ordering supports forward and backward.
  • order_by_field can be a field name string (for example "score") or a field id number (for example 123).

Field name and field id usage:

{
  "schema_name": "my_vertex",
  "selection": "(and (= score 1u64) (>= rank 10u64))",
  "order_by_field": "score"
}
{
  "schema_id": 42,
  "selection": "(and (= score 1u64) (>= rank 10u64))",
  "order_by_field": 123456789,
  "limit": 50,
  "offset": 0
}
  • Use field names in selection.
  • Use a field name string or field id number for order_by_field.
  • Use either schema_name or schema_id for schema references.

Response:

{
  "data": [
    {
      "id": "5QqkMJFr5s7J9wB8Q2kN1J",
      "header": {},
      "data": {}
    }
  ]
}

POST /v1/query/explain

Request:

{
  "schema_name": "my_vertex",
  "selection": "(= score 1u64)",
  "order_by_field": "score",
  "limit": 100
}

Response:

{
  "data": {
    "disjunction": false,
    "impossible": false,
    "clauses": [
      {
        "clause_kind": "range_scan",
        "reason": "indexable_eq",
        "estimated_rows": 42,
        "effective_rows": 42,
        "total_cost": 1.0
      }
    ]
  }
}

Graph Query Operations

These endpoints keep existing /v1/graph/* CRUD APIs unchanged and add Neb-powered graph lookup/traversal.

POST /v1/graph/query/vertices

Request shape is the same as /v1/query and returns matching graph vertices:

{
  "schema_name": "my_vertex",
  "selection": "(and (= score 1u64) (>= rank 10u64))",
  "ordering": "forward",
  "order_by_field": "score",
  "limit": 50,
  "offset": 0
}

POST /v1/graph/query/vertices/explain

Request shape is the same as /v1/query/explain.

POST /v1/graph/query/edges

Query edge body cells using the same request shape as /v1/query:

{
  "schema_name": "my_edge",
  "selection": "(= weight 7u64)",
  "order_by_field": "weight",
  "limit": 20
}
  • Edge query currently supports edge schemas with body fields.
  • Response includes cell_id, from_id, to_id, schema_id, edge_type, and body.

POST /v1/graph/query/traverse

Request:

{
  "seed": {
    "schema_name": "my_vertex",
    "selection": "(= score 1u64)",
    "limit": 20
  },
  "edge_schemas": [
    { "schema_name": "my_edge" }
  ],
  "direction": "outbound",
  "max_depth": 2
}
  • seed uses the same lookup shape as /v1/graph/query/vertices.
  • edge_schemas requires at least one schema ref (schema_name or schema_id).
  • direction supports outbound, inbound, and undirected.
  • max_depth defaults to 1 when omitted.
  • Traversal runs in two stages: Neb lookup for seed IDs first, then graph BFS expansion from those seeds.
  • Duplicate discovered vertices are de-duplicated before vertex materialization in the final response.

Response:

{
  "data": {
    "seed_ids": ["5QqkMJFr5s7J9wB8Q2kN1J"],
    "vertices": [],
    "edges": [
      {
        "id": "3Yv8v4Cw1W5Hk9p2LxQw9Q",
        "from_id": "5QqkMJFr5s7J9wB8Q2kN1J",
        "to_id": "2m8JqZfC2MbgQfE7x4oP6R",
        "schema_id": 77,
        "edge_type": "Directed"
      }
    ]
  }
}

GET /v1/graph/query/path/from/:source_id/to/:dest_id

Find a bounded BFS path between two vertex IDs (base58).

Query parameters:

  • edge_schema_ids (repeatable) - numeric edge schema IDs to traverse
  • edge_schema_id (optional) - single numeric edge schema ID
  • edge_schema_names (repeatable) - edge schema names to traverse
  • edge_schema_name (optional) - single edge schema name
  • direction (optional) - outbound (default), inbound, or undirected
  • max_depth (optional) - defaults to 5
  • max_visited (optional) - defaults to 100000

Example:

GET /v1/graph/query/path/from/5QqkMJFr5s7J9wB8Q2kN1J/to/2m8JqZfC2MbgQfE7x4oP6R?edge_schema_names=my_edge&direction=outbound&max_depth=6

Response:

{
  "data": {
    "found": true,
    "path": [
      "5QqkMJFr5s7J9wB8Q2kN1J",
      "3Yv8v4Cw1W5Hk9p2LxQw9Q",
      "2m8JqZfC2MbgQfE7x4oP6R"
    ],
    "visited": 42
  }
}

POST /v1/graph/query/path

Advanced path query with richer filters.

Request:

{
  "source_id": "5QqkMJFr5s7J9wB8Q2kN1J",
  "dest_id": "2m8JqZfC2MbgQfE7x4oP6R",
  "edge_schema_ids": [77],
  "edge_schema_names": ["my_edge"],
  "direction": "outbound",
  "max_depth": 6,
  "max_visited": 200000,
  "type_list_id": "3Yv8v4Cw1W5Hk9p2LxQw9Q",
  "vertex_filter": "(= status \"active\")",
  "edge_filter": "(> weight 0.5f64)"
}

Notes:

  • source_id, dest_id, and type_list_id are base58-encoded IDs.
  • vertex_filter and edge_filter are Lisp expressions parsed by Dovahkiin.
  • edge_schema_ids and edge_schema_names can be mixed.

Response shape is the same as the GET path endpoint:

{
  "data": {
    "found": true,
    "path": ["...", "..."],
    "visited": 42
  }
}

Cell CRUD

All cell CRUD endpoints require admin token when MORPHEUS_HTTP_ADMIN_TOKEN is set.

GET /v1/cells/:id

POST /v1/cells/:id

PUT /v1/cells/:id

DELETE /v1/cells/:id

Request (POST/PUT):

{
  "schema_id": 123,
  "data": {}
}

Legacy Schema Endpoints

These map to graph schema reads:

  • GET /v1/schemas
  • GET /v1/schemas/:name