Graph

Run Cypher queries with any Neo4j driver over Bolt TCP, or over HTTP for serverless. Cinch uses Ladybug (a fork of Kuzu), which speaks a Cypher dialect that is mostly compatible with Neo4j but has some important differences.

!

Schema-first

Unlike Neo4j, you must define node and relationship tables before inserting data. Use CREATE NODE TABLE and CREATE REL TABLE to set up your schema. See Graph Reference for the full list of differences.

1. Create a database

from cinchdb import Cinch

client = Cinch(api_key="ck_live_...", org="acme")
scope = client.scope("my-app", environment="production", project="api")
db = scope.create_database(type="graph", name="knowledge")

2. Connect over Bolt (TCP)

Use any Neo4j driver. The username is always neo4j.

from neo4j import GraphDatabase

driver = GraphDatabase.driver(
    "bolt://tcp.cinchdb.dev:7687",
    auth=("neo4j", "YOUR_DATABASE_TOKEN"),
)

with driver.session() as session:
    # 1. Define your schema (required before inserting data)
    session.run("CREATE NODE TABLE IF NOT EXISTS Person(name STRING PRIMARY KEY, age INT64)")
    session.run("CREATE REL TABLE IF NOT EXISTS KNOWS(FROM Person TO Person, since INT64)")

    # 2. Insert nodes and relationships
    session.run("CREATE (a:Person {name: 'Alice', age: 30})")
    session.run("CREATE (b:Person {name: 'Bob', age: 25})")
    session.run("""
        MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'})
        CREATE (a)-[:KNOWS {since: 2024}]->(b)
    """)

    # 3. Query
    result = session.run(
        "MATCH (p:Person)-[:KNOWS]->(friend) RETURN p.name, friend.name"
    )
    for record in result:
        print(f"{record['p.name']} knows {record['friend.name']}")

driver.close()
Hosttcp.cinchdb.dev
Port7687
Authneo4j / <your database token>

3. Connect over HTTP

For serverless and edge environments. Same database, same token.

import requests

ENDPOINT = "https://http.cinchdb.dev/v1/cypher"
HEADERS = {
    "Authorization": "Bearer YOUR_DATABASE_TOKEN",
    "Content-Type": "application/json",
}

# Define schema, then insert and query
resp = requests.post(ENDPOINT + "/batch", json={
    "statements": [
        {"query": "CREATE NODE TABLE IF NOT EXISTS Person(name STRING PRIMARY KEY, age INT64)"},
        {"query": "CREATE REL TABLE IF NOT EXISTS KNOWS(FROM Person TO Person, since INT64)"},
        {"query": "CREATE (a:Person {name: $name, age: $age})", "params": {"name": "Charlie", "age": 35}},
        {"query": "MATCH (p:Person) RETURN p.name, p.age"},
    ],
}, headers=HEADERS)
print(resp.json())
SinglePOST https://http.cinchdb.dev/v1/cypher
BatchPOST https://http.cinchdb.dev/v1/cypher/batch
AuthAuthorization: Bearer <token>
i

Good to know

  • Bolt versions 4.4 and 5.0-5.7 supported (drivers negotiate automatically).
  • Schema must be defined before data insertion (CREATE NODE TABLE, CREATE REL TABLE).
  • Every node table needs a PRIMARY KEY column.
  • Transactions supported (BEGIN/COMMIT/ROLLBACK via the driver API).
  • Read-only tokens cannot run write queries.

See Graph Reference for full Cypher capabilities, differences from Neo4j, and limitations.