Guides

Combine API documents

Turn related OpenAPI or GraphQL files into one logical Definition without forcing unrelated APIs into one Project.

A Project owns one logical Definition. That Definition may contain many files, but every operation should belong to one API product consumed, versioned, and released together.

Choose the right shape

What you haveWhat to do
One OpenAPI entrypoint with external $ref filesPoint Typeship at the entrypoint. Typeship resolves the graph itself.
Several complete OpenAPI descriptions that form one consumer productCreate and commit one combined entrypoint, then point Typeship at it.
GraphQL SDL split across filesUse whole-document #import "./file.graphql" directives from one root SDL file.
Independently consumed APIs with different audiences or release schedulesCreate separate Projects. Do not join them to save configuration.

Multi-file OpenAPI

OpenAPI already supports a document graph. Keep a small root file and reference path items or schemas by repository-relative path:

openapi: 3.1.0
info:
  title: Acme API
  version: 1.0.0
paths:
  /customers:
    $ref: ./paths/customers.yaml
components:
  schemas:
    Customer:
      $ref: ./components/schemas/customer.yaml

Set this root as the Definition entrypoint. Typeship records every resolved source document in the Definition Revision, watches referenced-file-only changes, and reports Diagnostics against the original file coordinates. You do not need to bundle this graph for Typeship.

Repository references must stay inside the connected repository. URL references must stay on the entrypoint's origin.

See Definitions for the resolution boundary and Spec compatibility for limits.

Several complete OpenAPI descriptions

Two complete descriptions do not become one API merely because they share a directory. Combine them only when their operations should ship to the same consumers under one compatibility and release policy.

Typeship does not execute repository build commands. Produce the combined document in your workflow and commit it, or serve it at a stable URL.

For OpenAPI 3.x, one option is Redocly CLI's experimental join command:

npx @redocly/cli@latest lint payments.yaml
npx @redocly/cli@latest lint customers.yaml
npx @redocly/cli@latest join payments.yaml customers.yaml \
  --output openapi/typeship.yaml

Use openapi/typeship.yaml as the Definition entrypoint. Reproduce it in CI and fail when the committed file drifts.

Before joining, resolve conflicts in:

  • paths and operation IDs;
  • tags and schemas;
  • security schemes; and
  • server semantics.

Do not use bundle for this case. Bundling follows $ref values from one root; joining combines independent root descriptions.

Multi-file GraphQL

Typeship composes whole SDL documents with simple import directives:

# schema.graphql
#import "./customers.graphql"
#import "./payments.graphql"

schema {
  query: Query
  mutation: Mutation
}

Each imported file contributes its complete SDL. Named import syntax is not supported, and duplicate or conflicting types fail resolution.

GraphQL endpoint, authentication, environment, scalar, and title settings remain on the Definition.

Keep APIs separate when ownership is separate

Use separate Projects when APIs have distinct consumers, authentication boundaries, version policies, owners, or release schedules. A shared repository does not require a shared Project. Each Project can point at a different entrypoint in that repository.

For AI agents

Inspect the repository before proposing composition. Configure an existing root directly when files are connected by $ref or whole-document GraphQL imports. If several OpenAPI roots form one product, add a deterministic committed join step. Ask the API owner before joining independently consumed APIs.

On this page