> ## Content Index
> Fetch the complete content index at: https://blogs.originchaindb.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# OpenAPI spec and the AI coding loop
- URL: https://blogs.originchaindb.com/openapi-spec-and-the-ai-coding-loop/
- Published: 2026-05-04T13:00:00.000Z
- Updated: 2026-11-07T16:42:06.000Z
- Description: An OpenAPI spec is what a coding agent reads to generate a client for your API. Ours is vanilla OpenAPI 3.1, one bearer scheme, published at /openapi.json.
- Author: OriginChainDB Team
- Tags: Engineering, openapi, ai-tools, sdk, developer-experience, #migrated-website, #byline-originchaindb

OriginChainDB publishes a vanilla OpenAPI 3.1 spec at `/openapi.json` because that is the file a coding agent reads when an engineer asks it to build a client. Nobody filed an issue asking for one. The spec is the floor the whole SDK-generation loop stands on, and a vendor without one is not reachable from inside the agents engineers actually use.

## The SDK-generation loop

Here is the workflow, and it is roughly universal now:

1. An engineer wants to call OriginChainDB from a Go service.
2. They open their coding agent and type: *“build me a Go client for OriginChain. Here’s the OpenAPI spec: `https://acme.originchain.ai/openapi.json` (illustrative URL).”*
3. The agent fetches the spec, reads the path patterns, response shapes, auth scheme, and error envelope, and either:
- runs `openapi-generator-cli generate -i... -g go -o./oc-client`, then patches the bits the generator gets wrong, **or**
- generates the client from scratch with full control over package layout, naming, and idiom.
1. Thirty seconds later, the engineer has a working `oc.NewClient(token).SQL(ctx,...)` they can drop into their service.

This loop runs hundreds of times a day across every database vendor that has a spec. The vendor never sees it - there is no telemetry, no sign-up, no email - but it is happening, and it is the dominant integration path.

If you do not ship a spec, you are invisible to that loop. The agent has no source of truth to read from; the engineer falls back to guessing path shapes from your docs page; the result is a half-broken client that gets thrown away. Worse: if your competitor’s spec *is* there, the agent silently picks the path of least resistance, and you lose the integration before the engineer ever read your homepage.

This is the shape of distribution in 2026\. Specs are the new SDKs.

## What our spec contains

`https://<tenant>.originchain.ai/openapi.json` and the canonical mirror at `https://originchaindb.com/openapi.json` are vanilla OpenAPI 3.1 - no extensions, no vendor-specific quirks, no auth flow that needs explanation. It is the simplest possible shape for a generator to consume.

**Auth.** One scheme: `bearerAuth`, HTTP `Authorization: Bearer <token>`. Every protected path declares it. There is no OAuth flow, no API-key header alternative, no session cookie. One auth path means generators produce one auth method, which means the agent doesn’t have to decide between three.

**Paths.** Six of them: one per query shape, plus schema introspection.

```
POST /v1/tenants/{tenant}/sql Typed SQL with bind params
POST /v1/tenants/{tenant}/ask Natural-language question → rows
POST /v1/tenants/{tenant}/vector/search HNSW top-k
POST /v1/tenants/{tenant}/fts/search BM25 full-text
POST /v1/tenants/{tenant}/graph/dijkstra Weighted shortest path
GET /v1/tenants/{tenant}/schemas Tenant table introspection
```

**Response shapes.** Every successful response is a `{ rows: [...], meta: {... } }` envelope. Every error is a `{ error: { code, message, details } }` envelope. The envelope is a *generated schema*, not a freehand example, so the generator emits a `Response<T>` wrapper type the SDK user can pattern-match on.

**Examples.** Each path has at least one `examples` block on the request body and one on the 200 response. Generators that consume examples (most of the modern ones do) lift them straight into the SDK as fixture tests.

## A 10-line example

Feed the spec to a coding agent in a fresh session:

```
Here is an OpenAPI spec: https://originchaindb.com/openapi.json

Generate a minimal TypeScript client with one method per path,
typed request and response, bearer-token auth, and a single
`OriginChain` class. No external deps beyond fetch.
```

What comes back is roughly:

```
export class OriginChain {
 constructor(private base: string, private token: string) {}
 private async post<T>(path: string, body: unknown): Promise<T> {
 const r = await fetch(`${this.base}${path}`, {
 method: "POST",
 headers: {
 "Authorization": `Bearer ${this.token}`,
 "Content-Type": "application/json",
 },
 body: JSON.stringify(body),
 });
 if (!r.ok) throw new Error(`${r.status}: ${await r.text}`);
 return r.json as Promise<T>;
 }
 sql<T = unknown>(req: { sql: string; params?: unknown[] }) {
 return this.post<{ rows: T[]; meta: object }>("/v1/tenants/{tenant}/sql", req);
 }
 ask<T = unknown>(req: { question: string }) {
 return this.post<{ rows: T[]; meta: object }>("/v1/tenants/{tenant}/ask", req);
 }
 vectorSearch<T = unknown>(req: {
 table: string; vector: number[]; k: number;
 metric?: "cosine" | "dot" | "l2";
 mode?: "fast" | "high_recall";
 filter?: Record<string, unknown>;
 }) {
 return this.post<{ rows: T[]; meta: object }>("/v1/tenants/{tenant}/vector/search", req);
 }
}
```

Thirty seconds, no human in the loop, working client. The whole point of shipping the spec is making this trajectory the default.

## What a static spec misses

Three things a vanilla OpenAPI spec cannot do, called out so the claim sheet is honest:

- **Runtime introspection.** The spec describes `GET /v1/tenants/{tenant}/schemas` but does not contain *your* tenant’s actual tables. The agent generating a client knows about the *shape* of the introspection call but not about your `products` table specifically. For that the agent calls `/v1/tenants/{tenant}/schemas` at runtime - which is the right answer (data shouldn’t live in the spec), but worth saying out loud.
- **Examples that match real tenant data.** The `examples` blocks in the spec are generic - `"sql": "SELECT * FROM products LIMIT 10"`. They are not your products. A generator that wants to produce *fixture-realistic* tests has to pull a sample from the tenant after auth, and most generators don’t go that far.
- **Type precision around the JSON-Plan trees.** OriginChainDB returns the executed plan tree in the `meta.plan` field for SQL responses, and the tree is recursive: `Scan` and `Filter` and `Project` and `HashJoin` are all variants of a `PlanNode` discriminated union. OpenAPI 3.1 supports `oneOf` discriminators, which we use, but most generators flatten the union to `unknown` rather than emit a tagged sum type. The user’s SDK ends up correct on the wire but loose at the type level. We accept this - the alternative is shipping a custom code generator, which is the kind of vendor lock-in we work hard to avoid.

None of these are reasons not to ship the spec. They are the reasons to ship the spec *and* the language SDKs we hand-write for the precision cases (TypeScript, Python, Go) - the spec is the floor, the SDK is the ceiling, and the agent loop fills in between them.

## What this is NOT

The spec at `/openapi.json` is the **public surface only**. It does not document:

- The internal management API for tenant provisioning (which is operator-only).
- The replication protocol between primary and follower (which is private wire format).
- The `/admin/*` endpoints (which are gated by a separate bearer scope).

We deliberately keep the spec narrow. Every endpoint in the spec is one we commit to maintaining the shape of across a major version. If it is in `/openapi.json`, it is part of the contract; if it is not, it is implementation detail and may move.

## Try it

The spec lives at [/openapi.json](https://originchaindb.com/openapi.json?ref=blogs.originchaindb.com). The hand-written SDKs and full reference docs live at [/docs/api](https://originchaindb.com/docs/api?ref=blogs.originchaindb.com). Both are stable surfaces; both are versioned in lockstep with the engine.