# Schema extensions

**Create schema extensions to add fields and types to your API.**

A schema extension is a GraphQL subgraph that the Commerce Integration Layer composes with the core subgraph. It's one of two ways to extend a Project's API, alongside [Managed API Extensions](/commerce-integration-layer/managed-api-extensions.md), which intercept writes rather than the schema; to decide between them, see [Choose an extension type](/commerce-integration-layer/extension-types.md). The extension code runs on commercetools, requiring no infrastructure management and supporting zero-downtime updates.

This page covers how a schema-extended query resolves and which types you can extend. It assumes knowledge of the federation concepts from [GraphQL federation](/commerce-integration-layer/graphql-federation.md), such as subgraphs, entities, keys, and the directives.

## How a schema-extended query resolves

The following sequence illustrates checkout enrichment: resolving a custom `deliveryEstimates` field on `Cart` from a carrier's API.

```mermaid title="Schema-extended query resolution"
sequenceDiagram
	autonumber
	participant SF as Storefront
	participant R as Router
	participant CORE as Core subgraph
	participant EXT as Your extension resolver
	participant CAR as Carrier API<br/>(allowlisted host)

	SF->>R: query { cart { … core fields …, deliveryEstimates { methodKey eta } } }<br/>Authorization: Bearer session token
	R->>R: Validate and plan against your Project's published schema
	R->>CORE: Resolve the cart, including the fields your<br/>extension named in @requires (shipping address, line items)
	CORE-->>R: Core cart data + entity stub for your field
	R->>EXT: Resolve Cart.deliveryEstimates<br/>(parent = { id } plus the @requires fields)
	EXT->>CAR: fetch(estimate request), credentials from ctx.config
	CAR-->>EXT: Delivery estimates
	EXT-->>R: Field value (or null on failure, so the rest of the response survives)
	R-->>SF: One merged response
```

This example has the following design constraints:

- `ShippingMethod` is not in the [entity catalog](/commerce-integration-layer/schema-extensions.md#entity-catalog), so custom shipping data attaches to the owning entity (`Cart`, here) or to a new root query, not to the shipping method itself.
- The extension **enriches** shipping data. Available shipping methods and costs are determined by Project configuration. Modifying them requires write-path logic.

## Entity catalog

These are the types you can extend. All are keyed by `id`; the ones with a `key` field can also be keyed by `key`.

| Type | `id` key | `key` key |
| --- | --- | --- |
| `Product` | yes | optional |
| `Customer`, `BusinessUnit`, `Category`, `ApprovalRule`, `RecurrencePolicy` | yes | yes |
| `Cart`, `Order`, `Quote`, `QuoteRequest`, `Review`, `ShoppingList`, `ApprovalFlow`, `RecurringOrder` | yes | n/a |
| `AssociateRole` | n/a | yes |

Value types, reference wrappers, embedded sub-objects (such as `LineItem` or `Address`), and product variants are not extensible. Compute derived fields on the owning entity instead.

## Further reading

Find in [Write schema extensions](/commerce-integration-layer/development/writing-schema-extensions.md) guidance on how to write the SDL and resolvers, and to manage the sandbox, configuration, local development, and publishing.

## Related pages

- [Area overview page with navigation](/commerce-integration-layer.md)
- [Previous page: Choose an extension type](/commerce-integration-layer/extension-types.md)
- [Next page: Managed API Extensions](/commerce-integration-layer/managed-api-extensions.md)
- [Search documentation and API specs](/search.md)