Graphon Engine

Get started

AI Draft

Create a namespace, add inline text, and retrieve your first answer with HTTP.

Create a namespace and collection, add a short incident report, then retrieve spans and an answer. Each step shows an HTTP request and an illustrative response.

Before you begin

You need a reachable Graphon Engine cluster and a cluster key from its operator. A cluster key can create namespaces. Use it for this walkthrough. In an application, issue narrower keys after provisioning.

Replace engine.example.com with the host of your cluster. Replace <GRAPHON_ENGINE_API_KEY> with your key in every Authorization header. Requests use HTTPS, except local loopback development. The examples are static; this docs site does not send them.

Register a status receiver before adding files. Call Create webhook with a scope and your HTTPS URL, and store the signing secret from the answer. Follow Handle jobs and events for setup and signature checks. This walkthrough uses a completion event, then one status read to confirm the result.

Example values

Resource IDs, timestamps, generation values, scores, and timings below are illustrative. Use the values returned by your own requests.

1. Check your cluster

Call Info to check authentication and discover the capabilities of this cluster. Confirm that search.modes includes hybrid and answer.efforts includes medium.

GET https://engine.example.com/info

GET /info HTTP/1.1
Host: engine.example.com
Authorization: Bearer <GRAPHON_ENGINE_API_KEY>

200 OK

{
  "name": "graphon-engine",
  "api_version": "1",
  "auth": {
    "required": true
  },
  "storage": {
    "primary": "graphon",
    "schemes": [
      "gs",
      "graphon"
    ]
  },
  "search": {
    "modes": [
      "keyword",
      "hybrid"
    ]
  },
  "answer": {
    "efforts": [
      "medium",
      "high"
    ]
  },
  "events": {
    "webhooks": 1,
    "types": [
      "job.updated",
      "file.status_changed",
      "collection.status_changed"
    ]
  }
}

events.webhooks reports the number of webhooks that this key can see. If it is zero, register a webhook before you rely on live notifications. A 401 means the key is missing, invalid, or revoked.

2. Create a namespace

A namespace is a tenant boundary. Create namespace makes acme. The name becomes part of the URLs used below. An Idempotency-Key identifies this logical write; reuse it only when retrying the same request.

POST https://engine.example.com/namespaces

POST /namespaces HTTP/1.1
Host: engine.example.com
Authorization: Bearer <GRAPHON_ENGINE_API_KEY>
Content-Type: application/json
Idempotency-Key: quickstart-acme-namespace

{
  "name": "acme",
  "display_name": "Acme",
  "exist_ok": true
}

201 Created · Location: /namespaces/ns_01J8Z3K4N5P6Q7R8S9T0V1W2X3

{
  "id": "ns_01J8Z3K4N5P6Q7R8S9T0V1W2X3",
  "name": "acme",
  "display_name": "Acme",
  "usage": {
    "collections": 0,
    "files": 0,
    "source_bytes": "0",
    "index_bytes": "0"
  },
  "created_at": "2026-10-06T12:00:00Z",
  "updated_at": "2026-10-06T12:00:00Z"
}

Retain the returned name and id. exist_ok: true returns 200 OK with the existing namespace if the name already exists. It does not update that namespace.

3. Create a collection

A collection is the set of files that Search and Answer use together. Create collection makes incident-logs. The default processing profile enables keyword, semantic, and graph processing.

POST https://engine.example.com/namespaces/acme/collections

POST /namespaces/acme/collections HTTP/1.1
Host: engine.example.com
Authorization: Bearer <GRAPHON_ENGINE_API_KEY>
Content-Type: application/json
Idempotency-Key: quickstart-incident-collection

{
  "name": "incident-logs",
  "display_name": "Incident logs",
  "exist_ok": true,
  "access_control": "off"
}

201 Created · Location: /namespaces/ns_01J8Z3K4N5P6Q7R8S9T0V1W2X3/collections/col_01J8Z3K4N5P6Q7R8S9T0V1W2X3

{
  "id": "col_01J8Z3K4N5P6Q7R8S9T0V1W2X3",
  "namespace": "acme",
  "name": "incident-logs",
  "display_name": "Incident logs",
  "status": "empty",
  "access_control": "off",
  "processing": {
    "keyword": true,
    "semantic": true,
    "graph": true
  },
  "index_generation": null,
  "file_counts": {
    "pending": 0,
    "indexing": 0,
    "ready": 0,
    "failed": 0
  },
  "created_at": "2026-10-06T12:00:00Z",
  "updated_at": "2026-10-06T12:00:00Z"
}

The new collection is empty. This walkthrough uses access_control: "off", so Search and Answer omit principals. If an existing collection uses enforced, use a fresh collection name or follow the access guide.

4. Add a file

Add file accepts inline text without a storage connector. The path starts with /. Metadata adds fields that your application can use in filters.

POST https://engine.example.com/namespaces/acme/collections/incident-logs/files

POST /namespaces/acme/collections/incident-logs/files HTTP/1.1
Host: engine.example.com
Authorization: Bearer <GRAPHON_ENGINE_API_KEY>
Content-Type: application/json
Idempotency-Key: quickstart-checkout-report-1

{
  "path": "/incidents/checkout.txt",
  "source": {
    "type": "inline",
    "content_type": "text/plain",
    "text": "Checkout stalled because the service exhausted its connection pool. Increase the pool size before the next deployment."
  },
  "metadata": {
    "environment": "production",
    "service": "checkout"
  }
}

202 Accepted

{
  "file": {
    "id": "fil_01J8Z3K4N5P6Q7R8S9T0V1W2X3",
    "path": "/incidents/checkout.txt",
    "status": "indexing",
    "stage": "engine_queued",
    "source": {
      "type": "inline",
      "content_type": "text/plain",
      "bytes": 118
    },
    "metadata": {
      "environment": "production",
      "service": "checkout"
    },
    "created_at": "2026-10-06T12:00:00Z",
    "updated_at": "2026-10-06T12:00:00Z"
  },
  "job": {
    "id": "job_01J8Z3K4N5P6Q7R8S9T0V1W2X3",
    "type": "index_file",
    "status": "running",
    "namespace": "acme",
    "collection": "incident-logs",
    "file_id": "fil_01J8Z3K4N5P6Q7R8S9T0V1W2X3",
    "error": null,
    "created_at": "2026-10-06T12:00:00Z",
    "updated_at": "2026-10-06T12:00:00Z"
  }
}

Save file.id and job.id. The file is processing. The response omits the write-only source.text and reports its UTF-8 byte count. Repeating this request with the same idempotency key returns the same result. A new request at the same path replaces the file content.

See Add a file for upload, storage URI, replacement, and failure examples.

5. Confirm the file is ready

1 · Request

202 Accepted

Retain file.id and job.id.

2 · Event

File ready

Verify the signature and event ID.

3 · Continue

Search or Answer

Use the now-ready content.

Missed notification? Read the saved job or file once to recover current state.
The add request returns a file ID and job ID. A registered webhook receives a signed status event. Use one status read after completion, or to recover after a missed event.

Wait for a verified file.status_changed event whose file_id matches your file and whose data.status is ready. Each POST holds a batch of events. The receiver must check the signature and deduplicate each event before using it. The body looks like this:

Incoming batch with a file.status_changed event

{
  "events": [
    {
      "id": "evt_01J8Z3K4N5P6Q7R8S9T0V1W2X3",
      "type": "file.status_changed",
      "occurred_at": "2026-10-06T12:01:00Z",
      "cluster": "graphon-engine",
      "namespace": "acme",
      "collection": "incident-logs",
      "job_id": "job_01J8Z3K4N5P6Q7R8S9T0V1W2X3",
      "file_id": "fil_01J8Z3K4N5P6Q7R8S9T0V1W2X3",
      "research_id": null,
      "data": {
        "status": "ready",
        "previous_status": "indexing"
      }
    }
  ]
}

Read the job once to confirm completion. This is a one-time check, not a polling loop. A missed event can use the same read to recover current state.

GET https://engine.example.com/jobs/job_01J8Z3K4N5P6Q7R8S9T0V1W2X3

GET /jobs/job_01J8Z3K4N5P6Q7R8S9T0V1W2X3 HTTP/1.1
Host: engine.example.com
Authorization: Bearer <GRAPHON_ENGINE_API_KEY>

200 OK

{
  "id": "job_01J8Z3K4N5P6Q7R8S9T0V1W2X3",
  "type": "index_file",
  "status": "succeeded",
  "namespace": "acme",
  "collection": "incident-logs",
  "file_id": "fil_01J8Z3K4N5P6Q7R8S9T0V1W2X3",
  "error": null,
  "created_at": "2026-10-06T12:00:00Z",
  "updated_at": "2026-10-06T12:01:00Z"
}

Read the file when you need its current source or metadata. Continue when it is ready. If the job failed, read error.code and error.message, correct the source, and submit a new add request.

GET https://engine.example.com/namespaces/acme/collections/incident-logs/files/fil_01J8Z3K4N5P6Q7R8S9T0V1W2X3

GET /namespaces/acme/collections/incident-logs/files/fil_01J8Z3K4N5P6Q7R8S9T0V1W2X3 HTTP/1.1
Host: engine.example.com
Authorization: Bearer <GRAPHON_ENGINE_API_KEY>

200 OK

{
  "id": "fil_01J8Z3K4N5P6Q7R8S9T0V1W2X3",
  "path": "/incidents/checkout.txt",
  "status": "ready",
  "stage": null,
  "source": {
    "type": "inline",
    "content_type": "text/plain",
    "bytes": 118
  },
  "metadata": {
    "environment": "production",
    "service": "checkout"
  },
  "created_at": "2026-10-06T12:00:00Z",
  "updated_at": "2026-10-06T12:01:00Z"
}

6. Search for spans

Search collection returns ranked files and the spans that matched. hybrid matches exact words and meaning together, so the question does not need the same wording as the report. The default result type groups spans by file.

POST https://engine.example.com/namespaces/acme/collections/incident-logs:search

POST /namespaces/acme/collections/incident-logs:search HTTP/1.1
Host: engine.example.com
Authorization: Bearer <GRAPHON_ENGINE_API_KEY>
Content-Type: application/json

{
  "query": "Why are checkout requests hanging?",
  "mode": "hybrid",
  "limit": 10
}

200 OK

{
  "request_id": "req_example_search",
  "index_generation": "generation-example",
  "execution": {
    "mode": "hybrid",
    "interpretation": "literal"
  },
  "results": [
    {
      "file_id": "fil_01J8Z3K4N5P6Q7R8S9T0V1W2X3",
      "path": "/incidents/checkout.txt",
      "content_type": "text/plain",
      "rank": 1,
      "score": 0.81,
      "spans": [
        {
          "file_id": "fil_01J8Z3K4N5P6Q7R8S9T0V1W2X3",
          "unit": "chars",
          "start": 0,
          "end": 67
        }
      ]
    }
  ],
  "timing_ms": {
    "retrieval": 34,
    "total": 47
  },
  "warnings": [],
  "next_cursor": null
}

Use file_id and path to identify the source. Each span in spans names a place in the file: here chars from start to end. Send spans to Read spans to get their text. score ranks these results. It is not a confidence percentage. next_cursor: null means there is no next page.

7. Ask a question

Answer collection writes an answer from the collection, with a list of sources for its citations.

POST https://engine.example.com/namespaces/acme/collections/incident-logs:answer

POST /namespaces/acme/collections/incident-logs:answer HTTP/1.1
Host: engine.example.com
Authorization: Bearer <GRAPHON_ENGINE_API_KEY>
Content-Type: application/json

{
  "query": "Why did checkout stall?",
  "effort": "medium"
}

200 OK

{
  "request_id": "req_example_answer",
  "answer": "Checkout stalled because the service exhausted its connection pool [[SRC:0001]].",
  "effort": "medium",
  "sources": [
    {
      "ref": "SRC:0001",
      "span": {
        "file_id": "fil_01J8Z3K4N5P6Q7R8S9T0V1W2X3",
        "unit": "chars",
        "start": 0,
        "end": 67
      },
      "path": "/incidents/checkout.txt",
      "content_type": "text/plain",
      "score": 0.81,
      "cited": true
    }
  ],
  "image_description": null,
  "usage": {
    "credits": 1
  }
}

The answer marker [[SRC:0001]] names the source whose ref is SRC:0001. Render that marker as a citation to the file and its span. Use your actual answer and sources. Generated wording can vary.

Next steps

Was this page helpful?
View as Markdown