{ "openapi": "3.1.0", "info": { "title": "Omnigraph API", "description": "HTTP API for the Omnigraph graph database", "license": { "name": "MIT", "identifier": "MIT" }, "version": "0.4.1" }, "paths": { "/branches": { "get": { "tags": [ "branches" ], "summary": "List all branches.", "description": "Returns branch names sorted alphabetically. Read-only.", "operationId": "listBranches", "responses": { "200": { "description": "List of branches", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BranchListOutput" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } } }, "security": [ { "bearer_token": [] } ] }, "post": { "tags": [ "branches" ], "summary": "Create a new branch.", "description": "Forks `name` off of `from` (defaults to `main`). The new branch shares\ntable data with its parent until it is mutated. Returns 409 if `name`\nalready exists.", "operationId": "createBranch", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BranchCreateRequest" } } }, "required": true }, "responses": { "200": { "description": "Branch created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BranchCreateOutput" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "409": { "description": "Branch already exists", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } } }, "security": [ { "bearer_token": [] } ] } }, "/branches/merge": { "post": { "tags": [ "branches" ], "summary": "Merge one branch into another.", "description": "Merges `source` into `target` (defaults to `main`). Outcome is one of\n`already_up_to_date`, `fast_forward`, or `merged`. Returns 409 with the\nlist of conflicts if the merge cannot be completed; the target is left\nunchanged in that case. **Destructive** to `target` on success.", "operationId": "mergeBranches", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BranchMergeRequest" } } }, "required": true }, "responses": { "200": { "description": "Branches merged", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BranchMergeOutput" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "409": { "description": "Merge conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } } }, "security": [ { "bearer_token": [] } ] } }, "/branches/{branch}": { "delete": { "tags": [ "branches" ], "summary": "Delete a branch.", "description": "**Irreversible.** Removes the branch pointer; commits remain reachable\nonly if referenced by another branch. Returns 404 if the branch does not\nexist.", "operationId": "deleteBranch", "parameters": [ { "name": "branch", "in": "path", "description": "Branch name to delete", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Branch deleted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BranchDeleteOutput" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "404": { "description": "Branch not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } } }, "security": [ { "bearer_token": [] } ] } }, "/change": { "post": { "tags": [ "mutations" ], "summary": "Apply a GQ mutation to a branch.", "description": "Writes to the named `branch` (defaults to `main`). Mutations are atomic\nper call and produce a new commit. Returns counts of nodes and edges\naffected. **Destructive**: on success the branch is updated; rejected\nmutations may still acquire locks briefly. Returns 409 on merge conflict.", "operationId": "change", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChangeRequest" } } }, "required": true }, "responses": { "200": { "description": "Mutation results", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChangeOutput" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "409": { "description": "Merge conflict", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } } }, "security": [ { "bearer_token": [] } ] } }, "/commits": { "get": { "tags": [ "commits" ], "summary": "List commits.", "description": "Filter by `branch` to get the commits on a single branch (most recent\nfirst); omit to list across all branches. Read-only.", "operationId": "listCommits", "parameters": [ { "name": "branch", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "List of commits", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommitListOutput" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } } }, "security": [ { "bearer_token": [] } ] } }, "/commits/{commit_id}": { "get": { "tags": [ "commits" ], "summary": "Get a single commit.", "description": "Returns the commit's manifest version, parent commit(s), and creation\nmetadata. Read-only.", "operationId": "getCommit", "parameters": [ { "name": "commit_id", "in": "path", "description": "Commit identifier", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Commit details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CommitOutput" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "404": { "description": "Commit not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } } }, "security": [ { "bearer_token": [] } ] } }, "/export": { "post": { "tags": [ "queries" ], "summary": "Stream the contents of a branch as NDJSON.", "description": "Emits one JSON object per line (`application/x-ndjson`). Filter with\n`type_names` (node/edge type names) and/or `table_keys`; both empty\nstreams the entire branch. Suitable for large exports — the response is\nstreamed, not buffered. Read-only.", "operationId": "export", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExportRequest" } } }, "required": true }, "responses": { "200": { "description": "Exported data as NDJSON", "content": { "application/x-ndjson": {} } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } } }, "security": [ { "bearer_token": [] } ] } }, "/healthz": { "get": { "tags": [ "health" ], "summary": "Liveness probe.", "description": "Returns server status and version. Unauthenticated; safe to call from any\ncaller. Use this to confirm the server is reachable before invoking other\nendpoints.", "operationId": "health", "responses": { "200": { "description": "Server is healthy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HealthOutput" } } } } } } }, "/ingest": { "post": { "tags": [ "mutations" ], "summary": "Bulk-ingest NDJSON data into a branch.", "description": "`data` is NDJSON with one record per line. `mode` controls behavior on\nexisting rows: `merge` upserts by id (default), `append` blindly inserts,\n`overwrite` replaces table contents. If `branch` does not exist it is\ncreated from `from` (defaults to `main`). **Destructive** when `mode` is\n`overwrite` or when ingest produces conflicting writes.", "operationId": "ingest", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IngestRequest" } } }, "required": true }, "responses": { "200": { "description": "Ingest results", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IngestOutput" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } } }, "security": [ { "bearer_token": [] } ] } }, "/read": { "post": { "tags": [ "queries" ], "summary": "Execute a GQ read query.", "description": "Runs the query in `query_source` against either a branch or a frozen\nsnapshot (mutually exclusive). When `query_source` defines multiple named\nqueries, pick one with `query_name`. `params` is a JSON object whose keys\nmatch the parameters declared by the query. Returns rows as a JSON array\nplus a `columns` list. Read-only.", "operationId": "read", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReadRequest" } } }, "required": true }, "responses": { "200": { "description": "Query results", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReadOutput" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } } }, "security": [ { "bearer_token": [] } ] } }, "/schema": { "get": { "tags": [ "schema" ], "summary": "Read the current schema source.", "description": "Returns the project's schema as a single string in `.pg` source form.\nUseful for clients that want to introspect available types and tables\nbefore constructing GQ queries. Read-only.", "operationId": "getSchema", "responses": { "200": { "description": "Current schema source", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SchemaOutput" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } } }, "security": [ { "bearer_token": [] } ] } }, "/schema/apply": { "post": { "tags": [ "mutations" ], "summary": "Apply a schema migration.", "description": "Diffs `schema_source` against the current schema and applies the resulting\nmigration steps (add/drop type, add/drop column, etc.). **Destructive**:\nsome steps drop data. Returns the list of steps applied; if `applied` is\nfalse the diff was unsupported and no changes were made.", "operationId": "applySchema", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SchemaApplyRequest" } } }, "required": true }, "responses": { "200": { "description": "Schema apply results", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SchemaApplyOutput" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } } }, "security": [ { "bearer_token": [] } ] } }, "/snapshot": { "get": { "tags": [ "snapshots" ], "summary": "Read the current snapshot of a branch.", "description": "Returns the manifest version plus per-table metadata (path, version, row\ncount) for every table on the branch. Defaults to `main` when `branch` is\nomitted. Read-only.", "operationId": "getSnapshot", "parameters": [ { "name": "branch", "in": "query", "required": false, "schema": { "type": [ "string", "null" ] } } ], "responses": { "200": { "description": "Database snapshot", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SnapshotOutput" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorOutput" } } } } }, "security": [ { "bearer_token": [] } ] } } }, "components": { "schemas": { "BranchCreateOutput": { "type": "object", "required": [ "uri", "from", "name" ], "properties": { "actor_id": { "type": [ "string", "null" ] }, "from": { "type": "string" }, "name": { "type": "string" }, "uri": { "type": "string" } } }, "BranchCreateRequest": { "type": "object", "required": [ "name" ], "properties": { "from": { "type": [ "string", "null" ], "description": "Parent branch to fork from. Defaults to `main`." }, "name": { "type": "string", "description": "Name of the new branch. Must not already exist." } } }, "BranchDeleteOutput": { "type": "object", "required": [ "uri", "name" ], "properties": { "actor_id": { "type": [ "string", "null" ] }, "name": { "type": "string" }, "uri": { "type": "string" } } }, "BranchListOutput": { "type": "object", "required": [ "branches" ], "properties": { "branches": { "type": "array", "items": { "type": "string" } } } }, "BranchMergeOutcome": { "type": "string", "enum": [ "already_up_to_date", "fast_forward", "merged" ] }, "BranchMergeOutput": { "type": "object", "required": [ "source", "target", "outcome" ], "properties": { "actor_id": { "type": [ "string", "null" ] }, "outcome": { "$ref": "#/components/schemas/BranchMergeOutcome" }, "source": { "type": "string" }, "target": { "type": "string" } } }, "BranchMergeRequest": { "type": "object", "required": [ "source" ], "properties": { "source": { "type": "string", "description": "Source branch whose commits will be merged." }, "target": { "type": [ "string", "null" ], "description": "Target branch that will receive the merge. Defaults to `main`." } } }, "ChangeOutput": { "type": "object", "required": [ "branch", "query_name", "affected_nodes", "affected_edges" ], "properties": { "actor_id": { "type": [ "string", "null" ] }, "affected_edges": { "type": "integer", "minimum": 0 }, "affected_nodes": { "type": "integer", "minimum": 0 }, "branch": { "type": "string" }, "query_name": { "type": "string" } } }, "ChangeRequest": { "type": "object", "required": [ "query_source" ], "properties": { "branch": { "type": [ "string", "null" ], "description": "Target branch. Defaults to `main`." }, "params": { "description": "JSON object whose keys match the mutation's declared parameters." }, "query_name": { "type": [ "string", "null" ], "description": "Name of the mutation to run when `query_source` declares multiple." }, "query_source": { "type": "string", "description": "GQ mutation source containing `insert`, `update`, or `delete` statements.\nMay declare multiple named mutations; pick one with `query_name`.", "example": "query insert_person($name: String, $age: I32) {\n insert Person { name: $name, age: $age }\n}" } } }, "CommitListOutput": { "type": "object", "required": [ "commits" ], "properties": { "commits": { "type": "array", "items": { "$ref": "#/components/schemas/CommitOutput" } } } }, "CommitOutput": { "type": "object", "required": [ "graph_commit_id", "manifest_version", "created_at" ], "properties": { "actor_id": { "type": [ "string", "null" ] }, "created_at": { "type": "integer", "format": "int64", "description": "Commit creation time as Unix epoch microseconds.", "example": 1714000000000000 }, "graph_commit_id": { "type": "string" }, "manifest_branch": { "type": [ "string", "null" ] }, "manifest_version": { "type": "integer", "format": "int64", "minimum": 0 }, "merged_parent_commit_id": { "type": [ "string", "null" ] }, "parent_commit_id": { "type": [ "string", "null" ] } } }, "ErrorCode": { "type": "string", "enum": [ "unauthorized", "forbidden", "bad_request", "not_found", "conflict", "too_many_requests", "service_unavailable", "internal" ] }, "ErrorOutput": { "type": "object", "required": [ "error" ], "properties": { "code": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ErrorCode" } ] }, "error": { "type": "string" }, "manifest_conflict": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ManifestConflictOutput", "description": "Set when the conflict is a publisher CAS rejection\n(`ManifestConflictDetails::ExpectedVersionMismatch`). The caller's\npre-write view of `table_key` was at version `expected` but the\nmanifest is now at `actual`. Refresh and retry." } ] }, "merge_conflicts": { "type": "array", "items": { "$ref": "#/components/schemas/MergeConflictOutput" } } } }, "ExportRequest": { "type": "object", "properties": { "branch": { "type": [ "string", "null" ], "description": "Branch to export. Defaults to `main`." }, "table_keys": { "type": "array", "items": { "type": "string" }, "description": "Restrict the export to these table keys. Empty exports all tables." }, "type_names": { "type": "array", "items": { "type": "string" }, "description": "Restrict the export to these node/edge type names. Empty exports all types." } } }, "HealthOutput": { "type": "object", "required": [ "status", "version" ], "properties": { "source_version": { "type": [ "string", "null" ] }, "status": { "type": "string" }, "version": { "type": "string" } } }, "IngestOutput": { "type": "object", "required": [ "uri", "branch", "base_branch", "branch_created", "mode", "tables" ], "properties": { "actor_id": { "type": [ "string", "null" ] }, "base_branch": { "type": "string" }, "branch": { "type": "string" }, "branch_created": { "type": "boolean" }, "mode": { "$ref": "#/components/schemas/LoadMode" }, "tables": { "type": "array", "items": { "$ref": "#/components/schemas/IngestTableOutput" } }, "uri": { "type": "string" } } }, "IngestRequest": { "type": "object", "required": [ "data" ], "properties": { "branch": { "type": [ "string", "null" ], "description": "Target branch. Created from `from` if it does not yet exist. Defaults to `main`." }, "data": { "type": "string", "description": "NDJSON payload: one record per line, each shaped\n`{\"type\": \"\", \"data\": {...}}`.", "example": "{\"type\": \"Person\", \"data\": {\"name\": \"Alice\", \"age\": 30}}\n{\"type\": \"Person\", \"data\": {\"name\": \"Bob\", \"age\": 25}}" }, "from": { "type": [ "string", "null" ], "description": "Parent branch used to create `branch` if it does not exist. Defaults to `main`." }, "mode": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/LoadMode", "description": "How existing rows are handled. Defaults to `merge`." } ] } } }, "IngestTableOutput": { "type": "object", "required": [ "table_key", "rows_loaded" ], "properties": { "rows_loaded": { "type": "integer", "minimum": 0 }, "table_key": { "type": "string" } } }, "LoadMode": { "type": "string", "description": "Shadow enum for documenting [`LoadMode`] in the OpenAPI schema.", "enum": [ "overwrite", "append", "merge" ] }, "ManifestConflictOutput": { "type": "object", "description": "Structured details for a publisher-level OCC failure. Surfaces alongside\nHTTP 409 when a write was rejected because the caller's pre-write view of\none table's manifest version was stale relative to the current head. The\nexpected/actual fields tell the client which table to refresh.", "required": [ "table_key", "expected", "actual" ], "properties": { "actual": { "type": "integer", "format": "int64", "minimum": 0 }, "expected": { "type": "integer", "format": "int64", "minimum": 0 }, "table_key": { "type": "string" } } }, "MergeConflictKindOutput": { "type": "string", "enum": [ "divergent_insert", "divergent_update", "delete_vs_update", "orphan_edge", "unique_violation", "cardinality_violation", "value_constraint_violation" ] }, "MergeConflictOutput": { "type": "object", "required": [ "table_key", "kind", "message" ], "properties": { "kind": { "$ref": "#/components/schemas/MergeConflictKindOutput" }, "message": { "type": "string" }, "row_id": { "type": [ "string", "null" ] }, "table_key": { "type": "string" } } }, "ReadOutput": { "type": "object", "required": [ "query_name", "target", "row_count", "rows" ], "properties": { "columns": { "type": "array", "items": { "type": "string" } }, "query_name": { "type": "string" }, "row_count": { "type": "integer", "minimum": 0 }, "rows": {}, "target": { "$ref": "#/components/schemas/ReadTargetOutput" } } }, "ReadRequest": { "type": "object", "required": [ "query_source" ], "properties": { "branch": { "type": [ "string", "null" ], "description": "Branch to read from. Mutually exclusive with `snapshot`. Defaults to `main`." }, "params": { "description": "JSON object whose keys match the query's declared parameters." }, "query_name": { "type": [ "string", "null" ], "description": "Name of the query to run when `query_source` declares multiple. Optional\nwhen only one query is declared." }, "query_source": { "type": "string", "description": "GQ query source. May declare one or more named queries; pick one with\n`query_name` if there is more than one.", "example": "query get_person($name: String) {\n match {\n $p: Person { name: $name }\n }\n return { $p.name, $p.age }\n}" }, "snapshot": { "type": [ "string", "null" ], "description": "Snapshot id to read from. Mutually exclusive with `branch`." } } }, "ReadTargetOutput": { "type": "object", "properties": { "branch": { "type": [ "string", "null" ] }, "snapshot": { "type": [ "string", "null" ] } } }, "SchemaApplyOutput": { "type": "object", "required": [ "uri", "supported", "applied", "step_count", "manifest_version", "steps" ], "properties": { "applied": { "type": "boolean" }, "manifest_version": { "type": "integer", "format": "int64", "minimum": 0 }, "step_count": { "type": "integer", "minimum": 0 }, "steps": { "type": "array", "items": {} }, "supported": { "type": "boolean" }, "uri": { "type": "string" } } }, "SchemaApplyRequest": { "type": "object", "required": [ "schema_source" ], "properties": { "schema_source": { "type": "string", "description": "Project schema in `.pg` source form. The diff against the current\nschema produces the migration steps that will be applied.", "example": "node Person {\n name: String @key\n age: I32?\n}\n\nedge Knows: Person -> Person" } } }, "SchemaOutput": { "type": "object", "required": [ "schema_source" ], "properties": { "schema_source": { "type": "string" } } }, "SnapshotOutput": { "type": "object", "required": [ "branch", "manifest_version", "tables" ], "properties": { "branch": { "type": "string" }, "manifest_version": { "type": "integer", "format": "int64", "minimum": 0 }, "tables": { "type": "array", "items": { "$ref": "#/components/schemas/SnapshotTableOutput" } } } }, "SnapshotTableOutput": { "type": "object", "required": [ "table_key", "table_path", "table_version", "row_count" ], "properties": { "row_count": { "type": "integer", "format": "int64", "minimum": 0 }, "table_branch": { "type": [ "string", "null" ] }, "table_key": { "type": "string" }, "table_path": { "type": "string" }, "table_version": { "type": "integer", "format": "int64", "minimum": 0 } } } }, "securitySchemes": { "bearer_token": { "type": "http", "scheme": "bearer" } } } }