# OpenAPI contract

> Download and use Hodoflow's release-matched HTTP contract for JSON:API, token exchange, and webhook ingestion.

The public [OpenAPI 3.0 document](/openapi.json) is the machine-readable
contract for Hodoflow's generated **JSON:API** surface plus reviewed manual
definitions for token exchange and webhook ingestion. Use it to discover paths,
inspect request and response schemas, configure a raw viewer, or generate a
client inside your own build. It is public and contains no tenant data or
credentials.

It is not a catalog of every HTTP route Hodoflow serves. Read the coverage
boundary before treating it as an application-wide API definition.

## What the document covers

| Surface | In `openapi.json`? | Authoritative companion |
|---|---:|---|
| JSON:API at `/api/json/v1` | Yes | [JSON:API conventions](/platform/json-api) |
| GraphQL at `/api/graphql` | No | [GraphQL SDL contract](/tools/graphql-sdl) |
| Token exchange at `/api/v1/oauth/token` | Yes | [Authentication](/authentication) |
| Webhook ingestion at `/api/v1/webhooks/:token` | Yes | [Webhook ingestion](/webhook-ingestion) |

Every path in the document is already absolute from the application origin:
generated resource paths include `/api/json/v1`, while the reviewed manual
paths include `/api/v1`. The public developer-host copy sets `servers[0].url`
to the application origin, not to the developer portal and not to an origin
with another API prefix. Join the server and path exactly once:

```text
servers[0].url                  https://hodoflow.com
path                            /api/json/v1/workflows
request URL                     https://hodoflow.com/api/json/v1/workflows
```

Do not append `/api/json/v1` to the server URL before passing the document to a
viewer or generator; doing so creates a doubled path.

## Download the release-matched document

Download the document from the same release as the portal:

```bash
export HODOFLOW_DEVELOPER_URL=https://developer.hodoflow.com
curl -fsS "$HODOFLOW_DEVELOPER_URL/openapi.json" -o hodoflow-openapi.json
```

Check the advertised API origin and JSON:API contract version before using it:

```bash
jq '{openapi, version: .info.version, servers}' hodoflow-openapi.json
```

A production document reports OpenAPI `3.0.0`, JSON:API contract version `v1`,
and one application-origin server. The `v1` value identifies this API surface;
it is not a release number and does not select the GraphQL schema version.

The document served at `/openapi.json` is the recommended input for external
tools because its server is explicit. The application also exposes a discovery
copy at `/api/json/v1/open_api`, but a client fetching that copy already needs
to know the application origin.

## Read an operation

Paths map an HTTP method to its stable `operationId`, purpose, parameters, body,
responses, errors, and product-facing tag.
For example, inspect the list-workflows operation with:

```bash
jq '.paths["/api/json/v1/workflows"].get' hodoflow-openapi.json
```

Interpret the important pieces as follows:

| OpenAPI location | Meaning in Hodoflow |
|---|---|
| `operationId`, `summary`, and `description` | Stable client name, concise action, and operation purpose |
| `security` and `components.securitySchemes.bearerAuth` | Send the short-lived access token as `Authorization: Bearer …`; token exchange is the unauthenticated exception |
| `x-hodoflow` | Surface, version, stability, exact scope, idempotency behavior, related guides, and reviewed errors |
| `parameters` | Only the query and path parameters accepted by that operation |
| `style: deepObject` | Serialize nested JSON:API parameters with brackets, such as `page[limit]=25` |
| `requestBody.content.application/vnd.api+json` | The JSON:API write document accepted by the operation |
| `responses` | Successful document schemas plus the shared error response |
| `components.schemas` | Resource, filter, input, and supporting object shapes referenced by operations |

The top-level bearer scheme applies to authenticated operations. For JSON:API,
safe methods require `api_read` and unsafe methods require `api_write`;
`x-hodoflow.scope` carries that exact decision. Webhook ingestion requires
`webhooks`. Token exchange has no bearer requirement because it produces the
bearer token.

Parameters are operation-specific. If `page`, a filter field, or a sort field
does not appear on an operation, do not send it. In particular, do not assume
that every collection paginates or that omission implies a default page size.
See [JSON:API conventions](/platform/json-api) for media types, filter syntax,
idempotency, response headers, and the error envelope.

## Generate a client safely

Hodoflow does not currently publish an official SDK. A client generated from
this document is your build artifact, so pin the downloaded input and review
the generator output before shipping it.

Use a generator that supports all of these OpenAPI 3.0 features:

- `deepObject` query serialization for `filter`, `page`, and sparse fieldsets;
- `application/vnd.api+json` request and response bodies;
- referenced schemas, nullable unions, enums, patterns, and numeric bounds;
- distinct create and update input schemas; and
- response bodies whose top-level JSON:API shape is `{data, included, meta}`.

Every public HTTP operation has a unique stable `operationId` and reviewed
summary. Still wrap generated client methods behind names you control: generator
naming and serialization choices remain build-tool behavior rather than part of
Hodoflow's runtime contract.

Also verify how your generator handles recursive filter objects and
`additionalProperties`. A generated method that flattens a deep-object filter
into an ordinary string will not send the same request the schema describes.
Compare one generated collection request with the bracketed examples in the
[first API request](/get-started/first-api-request) before adopting it broadly.

Generating from this file can create helpers for token exchange and webhook
ingestion. GraphQL remains outside OpenAPI and uses the
[GraphQL SDL](/schema.graphql). Do not move either manual HTTP endpoint under
the JSON:API `v1` base path.

## Detect contract changes

Keep the exact OpenAPI file used to generate a released client. On upgrade,
download the next file, normalize both documents, and review the diff before
regenerating:

```bash
jq -S . hodoflow-openapi.json > hodoflow-openapi.sorted.json
jq -S . hodoflow-openapi.next.json > hodoflow-openapi.next.sorted.json
diff -u hodoflow-openapi.sorted.json hodoflow-openapi.next.sorted.json
```

Review path and method removals, newly required inputs, narrower enums or
bounds, schema type changes, and response-shape changes first. Additive paths,
optional fields, and response properties can still affect strict decoders, so
exercise the generated client against representative responses after every
regeneration.

At runtime, record `x-api-version` and `x-request-id` from responses. The first
confirms which JSON:API contract served the request; the second is the
correlation identifier to retain when diagnosing a mismatch with support.

## Choose the matching human reference

Use the [curated API reference](/reference) for a browsable rendering with
guidance, or the secondary [raw Swagger viewer](/tools/swagger) to inspect the
document directly. Use [JSON:API conventions](/platform/json-api) for behavior
shared across resource operations, and the task guides for a complete request,
expected response, permissions, and recovery steps. The machine document
defines the wire shape; the human pages explain how to use it safely.
