Graphory logo

Graphory

Graph API Reference

REST API for searching, exploring, writing to, and managing your knowledge graph. All endpoints require authentication.

Base URL

API
https://api.graphory.io

Authentication

Include your API key in the Authorization header on every request:

Header
Authorization: Bearer gs_ak_your_api_key

Generate keys from Settings > API Keys or programmatically via the API Keys endpoint. Each key is scoped to a single organization. You will need your org_id for all endpoints.

Endpoints

The full endpoint reference below is auto-generated from the live OpenAPI spec at api.graphory.io/openapi.json. 89 endpoints across 9 groups (plus the standalone /health probe above). Request and response shapes match exactly what the server returns today.

Public health check

GET/health

Public Health

Returns the 12-check baseline as structured JSON. No authentication required - this endpoint is intended for status pages, uptime monitors, and load-balancer probes. Rate-limited per IP via the unauthenticated tier (120 req/min).

The full check result is cached for 10 seconds with a lock-and-refresh strategy, so polling at any rate produces at most one full check pass per cache window.

Auth: none

Response status

200 - "status": "ok" (all checks passed) or "status": "degraded" (one or more warnings, still serving)

503 - "status": "down" (one or more failures - page on-call)

Response body
{
  "status": "ok",
  "checks": [
    {"name": "FalkorDB", "status": "ok", "detail": "FalkorDB up, 3 graph(s): ...", "latency_ms": 12},
    {"name": "Graph API", "status": "ok", "detail": "Graph API responding on port 8001", "latency_ms": 4},
    ...
  ],
  "version": "15b2c20",
  "checked_at": "2026-05-03T18:42:11.123456+00:00"
}

Status pages should treat HTTP 200 as healthy and HTTP 503 as down. The status field in the response body has three possible values: ok, degraded, or down.

curl
curl -s 'https://api.graphory.io/health'
Live reference. This section is regenerated from api.graphory.io/openapi.json. 89 public endpoints across 9 groups. API version: 1.2.0.

Ingest

GET/ingest/schema

Ingest Schema

Return the ingest endpoint schema for documentation.

operationId: ingest_schema_ingest_schema_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/ingest/schema' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

POST/ingest

Ingest Data

Universal ingest endpoint. Accepts data from any system and writes .md files
with YAML frontmatter to the standard collector path.

By default returns as soon as the .md file is written on disk; the nightly
cron picks up new files at 4am. Pass ?sync=true to run the extraction
pipeline inline so the response only returns once the nodes are queryable
via /search. Sync mode is intended for benchmark adapters and tests - it
skips community detection and cross-source linking to keep latency reasonable.

Per-record entity field
-----------------------
Each record MUST carry an entity slug. We accept two key names so callers
are not forced to remember the API/file-format split:

- ``entity`` - the canonical /ingest field name.
- ``company`` - legacy alias matching the .md frontmatter contract
(CLAUDE.md still documents 'company' for the on-disk file format).

If both keys are present, ``entity`` wins. If neither is present (or the
slug isn't registered to the caller's org), the offending item is returned
with ``error="entity_not_registered"`` plus a structured ``hint`` telling
the caller to call ``register_business`` first. The hint also includes up
to 10 of the org's existing entity slugs so an AI agent can recover
without a second round-trip.

operationId: ingest_data_ingest_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Query parameters
FieldTypeRequiredDefaultDescription
syncbooleanoptionalfalseIf true, block until extraction+dedup+reclassify complete and the new nodes are queryable. Skips community detection and cross-source linking.
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/ingest' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

POST/ingest/test

Ingest Test

Test the ingest endpoint. Validates auth without creating data.

operationId: ingest_test_ingest_test_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/ingest/test' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

Admin

POST/admin/hard-delete-org/{org_id}

Admin Hard Delete Org

Immediately and permanently delete an org. Test-fixtures only.

This route refuses to touch any org whose `workos_id` field is not
exactly the sentinel string `"test_fixture"`. Production orgs MUST
use the soft-delete (POST /org/{id}/delete) + restore + nightly purge
flow; this route is the ephemeral-fixture escape hatch.

Returns a per-step result dict so the caller can verify each layer of
cleanup. Failures in any single layer are logged but do not abort the
other layers - a partial hard-delete is preferable to a leak.

operationId: admin_hard_delete_org_admin_hard_delete_org__org_id__post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
confirmbooleanoptionalfalseMust be true. Prevents accidental hard-delete via a stray POST.
confirm_org_idstringoptional""Must match the {org_id} in the path exactly. Replay-protection fence so an operator can't accidentally hard-delete the wrong org if they mis-typed the path.
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/admin/hard-delete-org/your-org-slug' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "confirm": false
}'

POST/admin/provision-org

Provision Org

Create or update an org with a FalkorDB graph. Idempotent.

If the org already exists, merges in any new fields (entities, owner, name)
without overwriting existing data. Safe to call multiple times.

operationId: provision_org_admin_provision_org_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
org_idstringrequired-Org identifier (slug or WorkOS org_id)
org_namestringoptional""Human-readable org name
ownerstringoptional""Owner identifier
entitiesarray<string>optional-Entity slugs for this org
workos_idstringoptional""WorkOS org ID if different from org_id
Responses

200 - Successful Response

Response body (200)
FieldTypeRequiredDefaultDescription
statusenum["created", "exists"]required-'created' on first provision, 'exists' when the org was already provisioned (idempotent merge path).
org_idstringrequired-The store key for the org (slug).
graph_namestringrequired-FalkorDB graph name (per-org sanitized identifier).
entitiesarray<string>?optional-Present only on the 'exists' (merge) path - lists the org's entity slugs after the merge. Absent on first 'created'.

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/admin/provision-org' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "org_id": "string"
}'

POST/admin/set-plan

Admin Set Plan

Admin-only: set an org's plan directly.

Body: {"org_id": "...", "plan": "free|pro|business|enterprise"}

operationId: admin_set_plan_admin_set_plan_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/admin/set-plan' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

Auth

GET/auth/me

Auth Me

Return the authenticated user's identity and org context.

Used by the MCP server for dynamic API key validation. RBAC v2:
response now also includes `user_id`, `owner` (bool), and
`graph_roles` (dict) sourced from membership.metadata.

operationId: auth_me_auth_me_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/auth/me' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

Collect

GET/collect/runs

List Collection Runs

List recent collection runs with status detection.

operationId: list_collection_runs_collect_runs_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/collect/runs' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/collect/runs/{run_id}/logs

Get Run Logs

Get log content for a specific collection run.

operationId: get_run_logs_collect_runs__run_id__logs_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
run_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/collect/runs/<run_id>/logs' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/collect/schedules

List Schedules

List all auto-scheduled collections.

operationId: list_schedules_collect_schedules_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/collect/schedules' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/collect/status

Collection Status

Check recent collection runs by inspecting log files.

operationId: collection_status_collect_status_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/collect/status' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

POST/collect/schedule

Manage Schedule

Add, remove, or list collection schedules via cron.

operationId: manage_schedule_collect_schedule_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
actionstringoptional"add"add | remove | list
entitystringoptional""Entity name
toolkitstringoptional""Toolkit name
schedulestringoptional"0 6 * * *"Cron expression
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/collect/schedule' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "action": "string"
}'

POST/collect/trigger

Trigger Collection Endpoint

Trigger data collection for an entity+toolkit pair.

Uses WorkOS Vault (BYOC) credentials only. Runs collection in a
background subprocess.

operationId: trigger_collection_endpoint_collect_trigger_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
entitystringoptional""Entity to collect for (e.g. groundstone-ai)
toolkitstringrequired-App/toolkit name (e.g. gmail, quickbooks)
days_backintegeroptional30
max_resultsintegeroptional500
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/collect/trigger' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "toolkit": "string"
}'

POST/collect/write-file

Write File

Write a parsed document to the collector data directory.

When body.sync is true, this also runs the extraction + identity + dedup +
reclassify pipeline inline (bounded by a 60s timeout) so the newly written
file is queryable via /search before the response returns. This closes the
race hit by MCP write tools (save_message, save_conversation, send_file,
import_from_api): write returns success, next search finds nothing.
The file is already durable on B2 before we touch the sync pipeline --
if sync fails, we attach sync_error to the response rather than failing
the write.

operationId: write_file_collect_write_file_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
entitystringrequired-
sourcestringoptional"upload"
filenamestringrequired-
contentstringrequired-
syncbooleanoptionalfalse
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/collect/write-file' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "entity": "string",
  "filename": "string",
  "content": "string"
}'

Misc

GET/

Root

operationId: root__get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Responses

200 - Successful Response

curl
curl -X GET 'https://api.graphory.io/' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

Org

GET/org/{org_id}/businesses

List Businesses Endpoint

List Business nodes registered in this org. Any member can read.

Returns a row per :Business node on the primary graph plus the
`org["entities"]` slug list so AIs can compare what's registered vs
what's been used. Use this before suggesting `register_business` so a
duplicate isn't proposed.

operationId: list_businesses_endpoint_org__org_id__businesses_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/businesses' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/connections

List Connections

List active Vault (BYOC) connections for an org, enriched with the
real status, endpoint count, source URL, and last sync timestamp from
the custom_configs sidecar and collection log directory.

Vault knows only credentials + created_at. Everything else lives on
disk next to the collector, so we fuse the two sources here so the
frontend never has to render "unknown" for data the server actually
has.

operationId: list_connections_org__org_id__connections_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/connections' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/conversation/schema

Get Conversation Schema

Step 1: Return the schema/instructions for saving a conversation.

The user's AI agent calls this first to learn the expected format,
then calls POST /org/{org_id}/conversation with the structured data.

operationId: get_conversation_schema_org__org_id__conversation_schema_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/conversation/schema' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/dossier/{entity}

Dossier

Composite cross-source profile of an entity in one call.

Composes search -> entity neighborhood -> traversal -> timeline ->
latent_connections so an agent doesn't have to chain 3-4 calls. Returns
a structured response plus a deterministic natural-language summary.

`timeline_days=0` disables the temporal filter on the timeline section
entirely. Useful for pulling the full historical record when the recent
window is empty.

operationId: dossier_org__org_id__dossier__entity__get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
entitystringrequired-
Query parameters
FieldTypeRequiredDefaultDescription
depthintegeroptional2
include_timelinebooleanoptionaltrue
include_latentbooleanoptionaltrue
timeline_daysintegeroptional90Lookback window in days for the timeline section. Pass 0 for unlimited (return all events regardless of date).
max_neighborsintegeroptional30
graph_idstringoptional"primary"
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/dossier/<entity>' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/entity/{node_id}

Get Entity

Get a node and its 1-hop neighborhood.

Declared as plain `def` (not `async def`) because the body calls
sync falkordb-py `session.run()`. FastAPI auto-dispatches plain-def
endpoints to the anyio threadpool, so concurrent calls don't
serialize on the asyncio event loop. See commit 4ff458f for the
same fix applied to /stats /search /dossier.

operationId: get_entity_org__org_id__entity__node_id__get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
node_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/entity/<node_id>' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/export

Request Org Export

Kick off an async export for the org.

Owner-only. Returns 202 with an export_id the client can poll via
GET /org/{org_id}/export/{export_id}. Two formats are supported:

- `format=zip` (default): every raw .md file the system has
collected or ingested, bundled with a manifest.json. This is the
user's SOURCE data and excludes the extracted graph.

- `format=graph-json`: a gzipped JSON-Lines snapshot of the org's
graph. Each line is a self-contained JSON-LD object. Nodes come
first, then edges. Per-node shape:

{
"@context": "https://schema.org",
"@type": "<node label>",
"id": "<node id>",
"name": "<display name>",
"properties": { ...all node props },
"provenance": { "source": "...", "confidence": 0.xx,
"authority": N, "valid_from": "..." }
}

Per-edge shape:

{
"@type": "Relationship",
"type": "<edge type>",
"from": "<source node id>",
"to": "<target node id>",
"properties": { ...all edge props },
"provenance": { "source": "...", "confidence": 0.xx,
"authority": N, "valid_from": "..." }
}

Scope covers every node and edge the user's graph contains.
Credentials, review-queue state, L3 decision rationales, cross-
customer ontology rules, and audit logs are excluded.

operationId: request_org_export_org__org_id__export_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Query parameters
FieldTypeRequiredDefaultDescription
formatstringoptional"zip"Export format. 'zip' returns every raw .md file the system has collected or ingested for the org. 'graph-json' returns a gzipped JSON-Lines (.jsonl.gz) dump of all nodes the user's graph contains followed by all edges, each carrying its full property bag plus a provenance sub-object (source, confidence, authority, valid_from). Sensitive keys (credentials, review-queue state, ontology rules, L3 decision rationales) are scrubbed; audit logs are not included.
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/export' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/export/{export_id}

Get Org Export Status

Poll status of an export. Owner-only. Returns the signed download
URL once status == 'ready'. Download URL is valid for 24h; re-polling
after expiry returns a fresh signed URL for the same zip.

operationId: get_org_export_status_org__org_id__export__export_id__get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
export_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/export/<export_id>' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/extraction-queue

Get Extraction Queue Endpoint

Return the caller's extraction queue rows plus org/global summary.

Self-scoped: the user only sees rows where user_id matches their own
auth context. Other org members' rows are NOT exposed; the "ahead of
you" counter is computed from the global queue without leaking the
other users' data.

operationId: get_extraction_queue_endpoint_org__org_id__extraction_queue_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Query parameters
FieldTypeRequiredDefaultDescription
statusstringoptional"all"
limitintegeroptional50
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/extraction-queue' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/file/{node_id}

Get File Content

Retrieve the raw .md source file content for a node.

Looks up the node by ID, reads file_path, and returns the file content.
This lets the user AI retrieve the original data behind any graph node.

operationId: get_file_content_org__org_id__file__node_id__get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
node_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/file/<node_id>' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/graphs

List Graphs Endpoint

List all graphs in this org with metadata + node/edge counts.

All org members can see the listing. Per-graph roles do NOT gate
the index (you can know a graph exists without being able to read
it). Use the role / member endpoints to check what you can read.

operationId: list_graphs_endpoint_org__org_id__graphs_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

Type: array<GraphMetadataResponse>

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/graphs' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/graphs/{graph_id}/marketplace-status

Marketplace Status Endpoint

Return marketplace publish state for a graph. Owner-only.

Includes derived fields (`days_active`, `public_tokens_count`) so the
dashboard can render a single panel without a second roundtrip.

operationId: marketplace_status_endpoint_org__org_id__graphs__graph_id__marketplace_status_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
graph_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/graphs/<graph_id>/marketplace-status' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/graphs/{graph_id}/public-tokens

List Public Tokens Endpoint

List all public tokens scoped to a specific graph. Owner-only.

Never returns the raw key or the SHA hash - only metadata. To
rotate a token, create a new one and revoke the old one.

operationId: list_public_tokens_endpoint_org__org_id__graphs__graph_id__public_tokens_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
graph_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

Type: array<PublicTokenResponse>

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/graphs/<graph_id>/public-tokens' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/keys

List Org Keys

List all gs_ak_* API keys for the org. Owner-only.

RBAC v2: keys no longer carry a `role` field directly; role flows
from the `user_id` -> membership.metadata link. Each row in the
response includes both for transparency.

operationId: list_org_keys_org__org_id__keys_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/keys' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/l3/review_pairs

Review Queue: List Pairs

Pull ambiguous review-queue pairs for a user's AI to adjudicate.

No tier gate - Free tier uses this endpoint as the entry point for the
BYOC-AI cleanup flow (the user's AI reads pairs, decides, and posts back
to the decisions endpoint). Each pair includes a `recommendation_hint`
with a pre-computed recommendation for the reviewer.

operationId: l3_review_pairs_endpoint_org__org_id__l3_review_pairs_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Query parameters
FieldTypeRequiredDefaultDescription
componentstringoptional"all"Review component filter (or 'all')
limitintegeroptional20
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/l3/review_pairs' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/latent_connections

Latent Connections

Find nodes in the same graph community as `entity_id` that are NOT
directly connected. Warm-intro / hidden-relationship candidates.

Communities are stored as a `community_id` property on each node
(populated by the nightly community detection job). If the entity has no
community assignment yet, returns an empty list with an explanatory note.

operationId: latent_connections_org__org_id__latent_connections_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Query parameters
FieldTypeRequiredDefaultDescription
entity_idstringrequired-Node ID to find latent connections for
limitintegeroptional10
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/latent_connections' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/members

List Org Members

List org members with their owner flag + graph_roles map.

Owners see all members. Non-owners see only their own row (so they
can read their own role without leaking the team list).

Each row is enriched with WorkOS user fields (email, first_name,
last_name) so the UI can render names without a second round-trip
per member.

operationId: list_org_members_org__org_id__members_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/members' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/memory-improvements

Get Memory Improvements

Read the Business Memory Improvements state for an org.

Any org member (or admin) may read. Shape:
{"enabled": bool, "updated_at": iso_str|null, "version": str}

operationId: get_memory_improvements_org__org_id__memory_improvements_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/memory-improvements' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/notifications

Get Org Notifications

Get pending notifications for an org.

Returns the same notifications array that is piggybacked on every
org-scoped API response. Useful for polling or initial load.

operationId: get_org_notifications_org__org_id__notifications_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/notifications' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/onboarding/status

Get Onboarding Status

Return the onboarding progress for an org.

Returns a checklist showing what has been set up and what is still
pending. An AI agent can use this to guide the user through setup.

operationId: get_onboarding_status_org__org_id__onboarding_status_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/onboarding/status' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/plan

Get Plan

Get the current plan, node usage, and review-queue eligibility for an org.

operationId: get_plan_org__org_id__plan_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/plan' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/plan/gating_log

Get Plan Gating Log

Recent queue-gate denials for this org, plus a month-to-date denial count.

Reads the review-decision audit store. If the store has not been
initialized yet (no automated reviews have happened) this returns an
empty log rather than 404.

operationId: get_plan_gating_log_org__org_id__plan_gating_log_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Query parameters
FieldTypeRequiredDefaultDescription
limitintegeroptional50
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/plan/gating_log' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/rules

Get Correction Rules

List all correction rules for this org.

operationId: get_correction_rules_org__org_id__rules_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/rules' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/stale_entities

Stale Entities

Find nodes that have been inactive for longer than the given number of days.
Surfaces forgotten follow-ups and dormant relationships.

operationId: stale_entities_org__org_id__stale_entities_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Query parameters
FieldTypeRequiredDefaultDescription
daysintegeroptional14
node_typestringoptional"Contact"Filter by node type. Call describe_schema for the live vocabulary.
limitintegeroptional20
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/stale_entities' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/stats

Graph Stats

Get graph statistics -- node/edge counts by type.

Declared as a sync `def` (not `async def`) because every line in
this function calls blocking FalkorDB Cypher via the synchronous
falkordb-py client. If we leave it `async def`, the four
`session.run()` calls below block the asyncio event loop for
~50-200 ms each, which serializes ALL concurrent requests across
the whole API process onto a single CPU - 100 concurrent /stats
hits collapse to ~1 req/sec throughput. With sync `def`, FastAPI
automatically dispatches the call to the anyio threadpool
(default 40 workers), which allows real concurrency under load.
The same anti-pattern exists on /search and /dossier; they are
fixed in the same way below.

operationId: graph_stats_org__org_id__stats_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/stats' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/suggestions

List Suggestions Endpoint

List improvement suggestions for an org.

Filters: category (merge_candidate, link_review,
uncertain_relationship, incomplete_contact, unconnected_entity),
status (pending, confirmed, rejected, superseded).

operationId: list_suggestions_endpoint_org__org_id__suggestions_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Query parameters
FieldTypeRequiredDefaultDescription
categorystring?optional-
statusstring?optional"pending"
limitintegeroptional50
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/suggestions' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/sync/history

Sync History

List recent sync jobs for an org.

operationId: sync_history_org__org_id__sync_history_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Query parameters
FieldTypeRequiredDefaultDescription
limitintegeroptional10
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/sync/history' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/sync/status

Sync Status

Check sync pipeline status.

If job_id is provided, returns that specific job.
Otherwise returns the most recent sync for this org.

operationId: sync_status_org__org_id__sync_status_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Query parameters
FieldTypeRequiredDefaultDescription
job_idstringoptional-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/sync/status' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/timeline

Timeline

Get recent activities for an entity, sorted by date.

Pass `days=0` to disable the temporal filter and return all events the
entity touches (still bounded by `limit`).

Declared as plain `def` (not `async def`) because the body calls
sync falkordb-py `session.run()`. FastAPI auto-dispatches plain-def
endpoints to the anyio threadpool, so concurrent calls don't
serialize on the asyncio event loop. See commit 4ff458f for the
same fix applied to /stats /search /dossier.

operationId: timeline_org__org_id__timeline_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Query parameters
FieldTypeRequiredDefaultDescription
entitystring?optional-
daysintegeroptional30Lookback window in days. Pass 0 for unlimited (return all events regardless of date).
limitintegeroptional50
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/timeline' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/usage

Org Usage

Get node count, plan limits, and usage percentage for an org.

operationId: org_usage_org__org_id__usage_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/usage' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/org/{org_id}/weekly_digest

Weekly Digest

Return the most recent weekly digest Asset node for this org.
The digest is generated every Monday 7 AM and covers the prior 7 days.
Plain ``def`` so the sync FalkorDB query dispatches to FastAPI's
threadpool instead of blocking the event loop. See commit 4ff458f.

operationId: weekly_digest_org__org_id__weekly_digest_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/org/your-org-slug/weekly_digest' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

POST/org/{org_id}/billing/checkout

Billing Checkout

Create a Stripe checkout session for upgrading.

Body: {"plan": "business" | "scale"}
Returns: {"url": "https://checkout.stripe.com/..."}

operationId: billing_checkout_org__org_id__billing_checkout_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/billing/checkout' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

POST/org/{org_id}/billing/portal

Billing Portal

Create a Stripe billing portal session for managing the subscription.

operationId: billing_portal_org__org_id__billing_portal_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/billing/portal' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

POST/org/{org_id}/browse

Browse Graph

Browse graph nodes in bulk without a search query. Returns nodes and edges.

Declared as plain `def` (not `async def`) because the body calls
sync falkordb-py `session.run()`. FastAPI auto-dispatches plain-def
endpoints to the anyio threadpool, so concurrent calls don't
serialize on the asyncio event loop. See commit 4ff458f for the
same fix applied to /stats /search /dossier.

operationId: browse_graph_org__org_id__browse_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
node_typestring?optional-Filter by node type
entitystring?optional-Filter by entity
limitintegeroptional5000
include_edgesbooleanoptionaltrueInclude edges between returned nodes
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/browse' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "node_type": "string"
}'

POST/org/{org_id}/businesses

Create Business Endpoint

Register a Business (a company the user owns) in this org. Owner-only.

Creates a :Business node on the org's primary graph (id=slug, plus name,
biz_type, description, industry, created_at, created_by) and appends the
slug to `org["entities"]` so the entity-access gate recognizes it.
Idempotent: if the slug already exists in `org["entities"]` we return the
existing record without rewriting it.

This is the ONLY path that should create new entity slugs. After it
succeeds, save_message / send_file / ingest / write_to_graph calls
targeting that slug pass the entity gate. Without prior registration,
the gate now rejects the write with a clear "call register_business"
error.

operationId: create_business_endpoint_org__org_id__businesses_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
namestringrequired-Display name (e.g. 'Groundstone Group').
biz_typestringrequired-One of: operating, holding, project, fund, vehicle, other.
slugstring?optional-Entity slug. Auto-derived from name if absent.
descriptionstring?optional-
industrystring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/businesses' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string",
  "biz_type": "string"
}'

POST/org/{org_id}/collection/{source}/status

Collection Phase Status

Return the current collection phase for a given org+source.

Shape: { phase, progress, message, updated_at } where phase is one of
idle | collecting | extracting | ready. Frontend polls this while a sync
is in flight. If we have no in-memory record, returns phase=unknown so
the client can fall back gracefully.

operationId: collection_phase_status_org__org_id__collection__source__status_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
sourcestringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/collection/<source>/status' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

POST/org/{org_id}/connections/vault

Register Vault Connection

Store BYOC credentials in the WorkOS Vault and auto-trigger the first sync.

Fire-and-forget: the collection runs as a background subprocess. The
caller sees an immediate 200, and the connections page picks up the new
row on its next 30s poll. Phase is tracked in the in-memory phase map
and is readable via POST /org/{org_id}/collection/{source}/status.

operationId: register_vault_connection_org__org_id__connections_vault_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
slugstringrequired-App slug (gmail, hubspot, etc.)
entitystringrequired-Entity this connection belongs to
credentialsobjectrequired-Credential fields
originstringoptional"manual"Where the connection was created: 'ai', 'manual', or 'unknown'
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/connections/vault' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "slug": "string",
  "entity": "string",
  "credentials": {}
}'

POST/org/{org_id}/conversation

Save Conversation

Step 2: Save structured conversation data.

Accepts EITHER:
- New format: {"data": "<YAML frontmatter + body>"} (2-step flow)
- Legacy format: ConversationRequest JSON (backwards compatible)

New format uses verb-to-edge mapping from the "who" field for deterministic
edge extraction. Creates Activity node + typed edges to matched contacts.

operationId: save_conversation_org__org_id__conversation_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/conversation' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

POST/org/{org_id}/delete

Delete Org

Soft-delete an org. Owner-only.

Stamps `deleted_at=now()` on the org record and records the reason. The
org is NOT immediately destroyed - a nightly purge job hard-deletes
graph state, raw files, and internal records once `deleted_at` is older
than GRAPHORY_PURGE_GRACE_DAYS (default 90).

Within the grace window the org can be undone via POST
/org/{org_id}/restore. After the window, data is unrecoverable.

Membership check uses the standard auth gate; the owner/admin gate
below prevents members from deleting the whole org.

operationId: delete_org_org__org_id__delete_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
reasonstring?optional-User-supplied reason for deletion. Stored for compliance review.
confirmbooleanoptionalfalseMust be true. Prevents accidental deletion via a stray POST.
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/delete' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "reason": "string"
}'

POST/org/{org_id}/graph/visual

Graph Visual

Optimized graph data for visualization. Returns a subset of the graph
designed to render smoothly in the browser (under 3K nodes typically).
Plain ``def`` (not ``async def``) so FastAPI dispatches the sync FalkorDB
calls to the threadpool. See commit 4ff458f.

Modes:
- overview: Top nodes by degree across all types. Good default view.
- entity: All nodes for a specific entity slug.
- community: All nodes in a specific graph community.
- search: Search results + their 1-hop neighbors.

operationId: graph_visual_org__org_id__graph_visual_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
modestringoptional"overview"overview, entity, community, search
entitystring?optional-Entity filter for entity mode
community_idinteger?optional-Community ID for community mode
querystring?optional-Search query for search mode
limitintegeroptional2000
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/graph/visual' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "mode": "string"
}'

POST/org/{org_id}/graphs

Create Graph

Create a new standalone graph in this org. Owner-only.

Provisions an empty FalkorDB graph keyed under `<primary>:<graph_id>`
and registers it in the org's `graphs` map with metadata (display
name, template, description, audit fields). The chosen template is
the ontology the KB extractor will use when the user later ingests
content into this graph.

operationId: create_graph_org__org_id__graphs_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
namestringrequired-Display name (e.g. 'Lender Directory').
templateenum["ai_chat", "coach", "documents", "general", "research"]required-KB template name to use as this graph's ontology. Built-in values: 'ai_chat', 'coach', 'documents', 'general', 'research'. 'operational' is a reserved sentinel for the primary graph and should not be passed on /graphs creation. Custom forks of the form 'custom_<name>' (created via the ontology endpoints) are also accepted. The server validates the final value against the kb_extractor template registry at request time.
descriptionstring?optional-Optional human description.
graph_idstring?optional-Slug for routing. Auto-derived from name if absent.
Responses

200 - Successful Response

Response body (200)
FieldTypeRequiredDefaultDescription
graph_idstringrequired-
graph_namestringrequired-
namestringrequired-
templatestringrequired-
descriptionstring?optional""
created_atstringrequired-
created_bystringrequired-
publishedbooleanoptionalfalse
publish_started_atstring?optional-
license_fee_usdnumber?optional-
node_countinteger?optional-
edge_countinteger?optional-

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/graphs' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string",
  "template": "ai_chat"
}'

POST/org/{org_id}/graphs/{graph_id}/public-tokens

Create Public Token Endpoint

Issue a new public read-only token scoped to a specific graph.

Owner-only. The token allows read-only access to ONE graph_id and
is rate-limited per token. Treat the returned `full_key` like a
Stripe publishable key: safe to embed in client-side code, but
revoke immediately if compromised.

Refuses to issue a public token for the `primary` graph because
operational graphs contain sensitive cross-source business data
that was never meant to be publicly shareable. Public tokens are
the right surface for standalone graphs created via POST
/org/{id}/graphs (Pillar 3) where the data is intentionally
publishable.

operationId: create_public_token_endpoint_org__org_id__graphs__graph_id__public_tokens_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
graph_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
labelstringrequired-Human-readable label, e.g. 'lender-directory-public-2026'.
rate_limit_per_minintegeroptional100Per-token rate limit (requests/minute). Burst capacity is a fixed 20 tokens. Default 100/min.
Responses

200 - Successful Response

Response body (200)
FieldTypeRequiredDefaultDescription
idstringrequired-
prefixstringrequired-
labelstringrequired-
graph_idstringrequired-
rate_limit_per_minintegerrequired-
created_atstringrequired-
created_bystringrequired-
last_used_atstring?optional-
usage_countintegeroptional0
full_keystring?optional-The full token. Returned ONCE on creation. Never returned from list / get / patch endpoints.

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/graphs/<graph_id>/public-tokens' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "label": "string"
}'

POST/org/{org_id}/graphs/{graph_id}/publish

Publish Graph Endpoint

Publish a standalone graph to the marketplace. Owner-only.

Flips `published=true` on the graph metadata, records
`publish_started_at`, stamps `license_fee_usd`, and attaches a
recurring Stripe subscription item priced at the marketplace fee
(default $50/mo from content/facts.yaml).

Refuses:
- graph_id == "primary" (operational graph cannot be marketplaced).
- already-published graphs (returns 409 with current state).
- missing `confirm=true` (returns 400 with fee details).

Stripe modes:
- STRIPE_SECRET_KEY unset: dry-run; flag flips, item id stamped as
"dry_run". Useful for tests + early customers.
- STRIPE_SECRET_KEY set but STRIPE_PRICE_PUBLISHED_GRAPH unset: 503
so the operator notices and configures the price id.
- Both set: real subscription item attached.

Public tokens issued for this graph remain valid; publishing is an
orthogonal signal. Use list_public_tokens / create_public_token to
manage them.

operationId: publish_graph_endpoint_org__org_id__graphs__graph_id__publish_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
graph_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
license_fee_usdnumberoptional50.0Per-month licensing fee for this published graph, in USD. Default reads from content/facts.yaml (marketplace.publish_fee_usd).
confirmbooleanoptionalfalseRequired: must pass true to confirm the recurring charge. Bare requests return 400 with the fee details so the caller can show a confirmation UI.
Responses

200 - Successful Response

Response body (200)
FieldTypeRequiredDefaultDescription
graph_idstringrequired-
graph_namestringrequired-
namestringrequired-
templatestringrequired-
descriptionstring?optional""
created_atstringrequired-
created_bystringrequired-
publishedbooleanoptionalfalse
publish_started_atstring?optional-
license_fee_usdnumber?optional-
node_countinteger?optional-
edge_countinteger?optional-

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/graphs/<graph_id>/publish' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "license_fee_usd": 0
}'

POST/org/{org_id}/graphs/{graph_id}/unpublish

Unpublish Graph Endpoint

Unpublish a graph and cancel its marketplace licensing fee. Owner-only.

Detaches the recurring Stripe subscription item (Stripe handles
proration per its defaults) and clears the publish metadata fields.
Existing public tokens for this graph remain valid -- revoke them
separately via revoke_public_token if you also want to cut off
embed access.

Refuses if the graph is not currently published (returns 400).

operationId: unpublish_graph_endpoint_org__org_id__graphs__graph_id__unpublish_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
graph_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

Response body (200)
FieldTypeRequiredDefaultDescription
graph_idstringrequired-
graph_namestringrequired-
namestringrequired-
templatestringrequired-
descriptionstring?optional""
created_atstringrequired-
created_bystringrequired-
publishedbooleanoptionalfalse
publish_started_atstring?optional-
license_fee_usdnumber?optional-
node_countinteger?optional-
edge_countinteger?optional-

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/graphs/<graph_id>/unpublish' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

POST/org/{org_id}/keys

Create Org Key

Create a new gs_ak_* API key for an org member. Owner-only.

RBAC v2: the key carries a `user_id` reference to the WorkOS user it
belongs to. Role is NOT a field on the key - it is sourced from
that user's membership.metadata at auth time.

`body.user_id` defaults to the caller's own user_id. To issue a key
on behalf of another existing org member (delegation), pass that
user's id explicitly. The target user must already be a member of
the org (no auto-invite).

operationId: create_org_key_org__org_id__keys_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
labelstringoptional"Member Key"Human-readable key label
user_idstring?optional-WorkOS user_id this key belongs to. Defaults to the caller's own user_id. Owners can pass a different user_id to issue a key on behalf of another existing org member. Admin caveat: the platform admin Bearer key carries an empty user_id and therefore CANNOT self-issue org-member keys via this endpoint - the admin must pass user_id='user_xxx' explicitly (the target user must already be a member of the org). A 400 is returned if the user_id cannot be resolved.
namestring?optional-Deprecated alias for label.
target_user_idstring?optional-Deprecated alias for user_id (owner-issued keys).
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/keys' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "label": "string"
}'

POST/org/{org_id}/l3/decisions

Review Queue: Record Decision

Record a decision from a user's AI (BYOC) on a review-queue pair.

Always available regardless of tier - this is the corrective surface
that lets a customer's own AI clean their graph for free. Decisions are
persisted to the training-data audit and tagged as BYOC-AI-produced.
A high-confidence SAME decision also triggers an actual merge via the
component's deterministic merge helper.

operationId: l3_decisions_endpoint_org__org_id__l3_decisions_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
pair_idstringrequired-Pair identifier returned by the review-pairs endpoint
componentstringrequired-Which review component the pair belongs to
contact_a_idstringrequired-
contact_b_idstringrequired-
decisionstringrequired-SAME | DIFFERENT | AMBIGUOUS
confidencenumberrequired-
reasoningstringoptional""Free-text rationale from the reviewer
user_agent_idstringoptional"user_ai_byoc"Identifier for the client that produced this decision
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/l3/decisions' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "pair_id": "string",
  "component": "string",
  "contact_a_id": "string",
  "contact_b_id": "string",
  "decision": "string",
  "confidence": 0
}'

POST/org/{org_id}/l3/merge/{decision_id}/revert

Review Queue: Revert Merge

Flag an AI-verified merge as wrong. This is the highest-value training
signal we collect - the only real ground truth - so the revert is
persisted to the audit trail and back-linked to the originating decision.

IMPORTANT: This endpoint only updates the audit trail. It does NOT
actually un-merge the contacts in the graph store - structural un-merge is
a separate graph-shape operation that is not part of this endpoint. A
user's AI should treat a successful 200 response as "your correction was
logged for training" and surface that to the user, not as "the merge has
been undone."

operationId: l3_revert_merge_endpoint_org__org_id__l3_merge__decision_id__revert_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
decision_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
reasonstringoptional""Why this merge was wrong (free text, max 500 chars)
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/l3/merge/<decision_id>/revert' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "reason": "string"
}'

POST/org/{org_id}/members/invite

Invite Org Member

Send a WorkOS invitation for a new org member. Owner-only.

Replaces the legacy `frontend/src/app/api/org/members POST` route,
which had no owner check. RBAC v2: only org owners may invite. The
invitee's role on graphs is the default ('viewer'); owner status is
not auto-granted via invite - use the explicit
`PUT /members/{user_id}/owner` endpoint after acceptance.

operationId: invite_org_member_org__org_id__members_invite_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
emailstringrequired-Email address of the user to invite.
rolestring?optional"member"WorkOS role slug for the invitation. Defaults to 'member'. Owner status is granted separately via PUT /org/{org_id}/members/{user_id}/owner after the invitee accepts the invitation.
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/members/invite' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "email": "string"
}'

POST/org/{org_id}/memory-improvements

Set Memory Improvements

Set the Business Memory Improvements state for an org. Owner-only.

- enabled=True -> org has Business Memory Improvements ON
- enabled=False -> org has Business Memory Improvements OFF;
stamps memory_improvements_updated_at=now

Every change is appended to an audit trail under
orgs[key]["memory_improvements_audit"] for compliance review. Each
entry's `from`/`to` fields capture the boolean enabled-state directly.

operationId: set_memory_improvements_org__org_id__memory_improvements_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Query parameters
FieldTypeRequiredDefaultDescription
enabledbooleanrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/memory-improvements' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

POST/org/{org_id}/notifications/dismiss

Dismiss Notification

Invalidate the notification cache for an org.

Call this after the user has seen or acted on notifications.
Forces a fresh recalculation on the next request.

operationId: dismiss_notification_org__org_id__notifications_dismiss_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/notifications/dismiss' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

POST/org/{org_id}/ontology/propose

Propose Ontology Endpoint

Propose a custom ontology for a domain via claude -p. Owner-only.

Returns a JSON proposal. Nothing is persisted - the user must call
POST /ontology/save to commit. Iterate via the `refinement` field.

operationId: propose_ontology_endpoint_org__org_id__ontology_propose_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
domain_descriptionstringrequired-Plain-English description of the domain.
refinementstring?optional-Follow-up adjustment for an iterative round.
base_templatestring?optional-Existing template to fork (e.g. 'general').
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/ontology/propose' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "domain_description": "string"
}'

POST/org/{org_id}/ontology/save

Save Ontology Template Endpoint

Persist a proposed ontology to a custom KB template. Owner-only.

The saved template is immediately usable as
`template="custom_<name>"` by POST /org/{id}/graphs.

operationId: save_ontology_template_endpoint_org__org_id__ontology_save_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
namestringrequired-Slug. Stored on disk as `custom_<name>.py`.
proposalobjectrequired-The dict returned by /propose_ontology (or a hand-edited version with the same shape).
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/ontology/save' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string",
  "proposal": {}
}'

POST/org/{org_id}/plan

Set Plan

Change an org's plan.

- 400 if plan is not in PLAN_LIMITS
- 404 if org not found
- Downgrades always succeed

Plan changes are gated by admin auth + the Stripe webhook path.

operationId: set_plan_org__org_id__plan_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
planstringrequired-One of: free, pro, business, enterprise
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/plan' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "plan": "string"
}'

POST/org/{org_id}/restore

Restore Org

Restore a soft-deleted org. Owner-only.

Clears deleted_at / deletion_reason / purge_scheduled_for, records an
audit entry, and resumes normal read/write access. Refuses to restore
orgs whose grace period has expired (the purge script will execute
imminently or already has). Refuses to restore orgs that aren't in a
soft-deleted state (idempotent no-op via 400, not a silent success).

operationId: restore_org_org__org_id__restore_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/restore' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

POST/org/{org_id}/search

Search

Keyword search across an org's graph.

Runs two search paths in parallel:
1. Graph-property keyword search across node names and metadata
2. Full-text search across document body text (sidecar index)

Results are merged and deduplicated. Each result carries a match_source
field: "fts" for body-content matches, "graph" for node-property matches,
"both" if found in both indexes.

operationId: search_org__org_id__search_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
qstringrequired-Search query text
node_typestring?optional-Filter by node type. Call describe_schema for the live vocabulary.
entitystring?optional-Filter by entity within the org
limitintegeroptional20
expanded_termsarray<string>?optional-Synonyms/related terms for broader full-text matching
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/search' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "q": "string"
}'

POST/org/{org_id}/suggestions/batch_merge

Batch Merge Suggestions Endpoint

Confirm many merge_candidate suggestions in a single call.

operationId: batch_merge_suggestions_endpoint_org__org_id__suggestions_batch_merge_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
suggestion_idsarray<string>optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/suggestions/batch_merge' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "suggestion_ids": []
}'

POST/org/{org_id}/suggestions/{suggestion_id}/confirm

Confirm Suggestion Endpoint

Confirm a suggestion and apply its write-back action.

For merge_candidate suggestions this triggers a graph merge via
harness.dedup_contacts.merge_contacts. Other categories mark the
suggestion accepted without performing a graph write.

operationId: confirm_suggestion_endpoint_org__org_id__suggestions__suggestion_id__confirm_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
suggestion_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/suggestions/<suggestion_id>/confirm' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

POST/org/{org_id}/suggestions/{suggestion_id}/reject

Reject Suggestion Endpoint

Reject a suggestion. The reason is persisted inside the payload.

operationId: reject_suggestion_endpoint_org__org_id__suggestions__suggestion_id__reject_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
suggestion_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
reasonstringoptional""
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/suggestions/<suggestion_id>/reject' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "reason": "string"
}'

POST/org/{org_id}/sync

Trigger Sync

Trigger the full extraction + identity resolution + reclassification pipeline.

Runs in background. Returns immediately with a job_id.
Idempotent - safe to call multiple times. If a sync is already
running for this org, returns the existing job info.

operationId: trigger_sync_org__org_id__sync_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/sync' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

POST/org/{org_id}/traverse

Traverse

Multi-hop traversal from a starting node.

Declared as plain `def` (not `async def`) because the body calls
sync falkordb-py `session.run()`. FastAPI auto-dispatches plain-def
endpoints to the anyio threadpool, so concurrent calls don't
serialize on the asyncio event loop. See commit 4ff458f for the
same fix applied to /stats /search /dossier.

operationId: traverse_org__org_id__traverse_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
start_idstringrequired-Starting node ID
depthintegeroptional2
edge_typesarray<string>?optional-Filter by edge types
limitintegeroptional200Max edges per page
cursorstring?optional-Pagination cursor (opaque). Pass next_cursor from previous response.
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/traverse' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "start_id": "string"
}'

POST/org/{org_id}/write

Write Back

Write-back endpoint with confidence gating.

Writes are confidence-gated. Low-confidence writes enter a review queue
rather than touching the graph; exact bands are server-controlled.

operationId: write_back_org__org_id__write_post

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
actionenum["upsert_node", "create_edge", "correction", "merge"]required-One of: 'upsert_node', 'create_edge', 'correction', 'merge'. Note: the MCP tool 'write_to_graph' maps friendly aliases ('add'/'connect'/'correct') onto these; the HTTP API does NOT. Pass the canonical value when calling /write directly.
labelstring?optional-
node_idstring?optional-
propertiesobject?optional-
from_idstring?optional-
to_idstring?optional-
edge_typestring?optional-
confidencenumberoptional0.5
evidencestring?optional-
loser_idstring?optional-
winner_idstring?optional-
Responses

200 - Successful Response

400 - Invalid action. Valid actions are 'upsert_node', 'create_edge', 'correction', 'merge'. The HTTP API does NOT translate MCP-friendly aliases like 'add'/'connect'.

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X POST 'https://api.graphory.io/org/your-org-slug/write' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "action": "upsert_node"
}'

PUT/org/{org_id}/members/{user_id}/owner

Set Member Owner

Grant or revoke owner status for an org member. Owner-only.

Refuses to demote the LAST remaining owner of the org so the org
cannot be left without an admin.

operationId: set_member_owner_org__org_id__members__user_id__owner_put

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
user_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
ownerbooleanrequired-True to grant owner status, false to revoke.
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X PUT 'https://api.graphory.io/org/your-org-slug/members/<user_id>/owner' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "owner": false
}'

PUT/org/{org_id}/members/{user_id}/role

Set Member Graph Role

Set the per-graph role for an org member. Owner-only.

Updates `membership.metadata.graph_roles[graph_id] = role`. The owner
flag is unchanged - use PUT /members/{user_id}/owner for that.

operationId: set_member_graph_role_org__org_id__members__user_id__role_put

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
user_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
graph_idstringoptional"primary"Graph this role applies to. 'primary' = the org's default operational graph.
rolestringrequired-Per-graph role: 'editor' or 'viewer'. (Owners get implicit editor everywhere; use the /owner endpoint to change owner status.)
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X PUT 'https://api.graphory.io/org/your-org-slug/members/<user_id>/role' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "role": "string"
}'

PATCH/org/{org_id}/graphs/{graph_id}/public-tokens/{token_id}

Update Public Token Endpoint

Update label and/or rate_limit_per_min on a public token. Owner-only.

Refuses to change the bound `graph_id` - rotate the token instead
(create a new token on the new graph, revoke this one).

operationId: update_public_token_endpoint_org__org_id__graphs__graph_id__public_tokens__token_id__patch

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
graph_idstringrequired-
token_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body
FieldTypeRequiredDefaultDescription
labelstring?optional-If set, the new label.
rate_limit_per_mininteger?optional-If set, the new rate limit.
Responses

200 - Successful Response

Response body (200)
FieldTypeRequiredDefaultDescription
idstringrequired-
prefixstringrequired-
labelstringrequired-
graph_idstringrequired-
rate_limit_per_minintegerrequired-
created_atstringrequired-
created_bystringrequired-
last_used_atstring?optional-
usage_countintegeroptional0
full_keystring?optional-The full token. Returned ONCE on creation. Never returned from list / get / patch endpoints.

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X PATCH 'https://api.graphory.io/org/your-org-slug/graphs/<graph_id>/public-tokens/<token_id>' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "label": "string"
}'

DELETE/org/{org_id}/entity/{node_id}

Delete Entity

Delete a node from the graph. Only nodes created via API write (provenance_source in api_write, ai_agent, test) can be deleted.

operationId: delete_entity_org__org_id__entity__node_id__delete

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
node_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X DELETE 'https://api.graphory.io/org/your-org-slug/entity/<node_id>' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

DELETE/org/{org_id}/graphs/{graph_id}

Delete Graph Endpoint

Delete a standalone graph. Owner-only.

Refuses to delete the `primary` graph (use the org-level delete
instead). Refuses to delete any graph with `published=true` (must
unpublish first). Requires `{"confirm": true}` in the body to
actually proceed -- a bare DELETE returns a description of what
would happen.

operationId: delete_graph_endpoint_org__org_id__graphs__graph_id__delete

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
graph_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Request body

Body type: DeleteGraphRequest?

Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X DELETE 'https://api.graphory.io/org/your-org-slug/graphs/<graph_id>' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'

DELETE/org/{org_id}/graphs/{graph_id}/public-tokens/{token_id}

Revoke Public Token Endpoint

Revoke a public token immediately. Owner-only.

Removes the entry from org.metadata.public_tokens and refreshes the
cache so subsequent requests with the revoked token get 401.

operationId: revoke_public_token_endpoint_org__org_id__graphs__graph_id__public_tokens__token_id__delete

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
graph_idstringrequired-
token_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X DELETE 'https://api.graphory.io/org/your-org-slug/graphs/<graph_id>/public-tokens/<token_id>' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

DELETE/org/{org_id}/keys/{key_id}

Revoke Org Key

Revoke a member key by its id. Owner-only.

Refuses to revoke the caller's own key (footgun). Refuses to revoke
the only key tied to the only org owner (would strand the org).

operationId: revoke_org_key_org__org_id__keys__key_id__delete

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
key_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X DELETE 'https://api.graphory.io/org/your-org-slug/keys/<key_id>' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

DELETE/org/{org_id}/rules/{rule_id}

Remove Correction Rule

Delete a correction rule.

operationId: remove_correction_rule_org__org_id__rules__rule_id__delete

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
org_idstringrequired-
rule_idstringrequired-
Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X DELETE 'https://api.graphory.io/org/your-org-slug/rules/<rule_id>' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

Orgs

GET/orgs

List Orgs

List orgs the current user has access to.

operationId: list_orgs_orgs_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Headers
FieldTypeRequiredDefaultDescription
X-User-Idstring?optional-
X-User-Emailstring?optional-
X-Org-Idstring?optional-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/orgs' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

Plans

GET/plans

List Plans

Public plan catalog -- powers the pricing page. No auth required.

operationId: list_plans_plans_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Responses

200 - Successful Response

curl
curl -X GET 'https://api.graphory.io/plans' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

Systems

GET/systems

List Systems

List all known data source systems with training status.

operationId: list_systems_systems_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Responses

200 - Successful Response

curl
curl -X GET 'https://api.graphory.io/systems' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/systems/priorities

List System Priorities

List untrained systems ranked by training priority (most impactful first).

operationId: list_system_priorities_systems_priorities_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Responses

200 - Successful Response

curl
curl -X GET 'https://api.graphory.io/systems/priorities' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/systems/untrained

List Untrained Systems

List systems that don't have trained extractors yet.

operationId: list_untrained_systems_systems_untrained_get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Responses

200 - Successful Response

curl
curl -X GET 'https://api.graphory.io/systems/untrained' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

GET/systems/{name}

Get System Details

Get details for a specific system.

operationId: get_system_details_systems__name__get

Auth: Authorization: Bearer gs_ak_YOUR_KEY

Path parameters
FieldTypeRequiredDefaultDescription
namestringrequired-
Responses

200 - Successful Response

422 - Validation Error

Response body (422)
FieldTypeRequiredDefaultDescription
detailarray<ValidationError>optional-
curl
curl -X GET 'https://api.graphory.io/systems/<name>' \
  -H 'Authorization: Bearer gs_ak_YOUR_KEY'

Error Handling

The API returns standard HTTP status codes:

CodeMeaning
200Success
400Bad request - check your parameters
401Unauthorized - invalid or missing API key
403Forbidden - key does not have access to this organization
404Not found - item or organization does not exist
429Rate limited - slow down requests
500Server error - try again or contact support

Error responses include a JSON body:

JSON
{
  "detail": "Organization not found"
}