# Get started with the Commerce Integration Layer

**Enable the Commerce Integration Layer, explore your Project's API, and publish your first extension.**

This guide walks you from a one-time setup step through your first query and your first published extension. For the federation concepts behind extensions, see [GraphQL federation](/commerce-integration-layer/graphql-federation.md). To decide between a schema extension and a Managed API Extension, see [Choose an extension type](/commerce-integration-layer/extension-types.md).

## Enable the Commerce Integration Layer

The Commerce Integration Layer is enabled per Project.

### Requirements

- A commercetools Composable Commerce Project.
- Access to the Commerce Integration Layer, requested from your commercetools Account Representative. See [Enrollment](/commerce-integration-layer/overview.md#enrollment) for more details.
- The Merchant Center `Manage API Clients` scope, to complete activation.

After your Project is enrolled, open the Commerce Integration Layer application in the Merchant Center and activate the Experience API.

Once enrolled and activated, the Experience API for the Project is live and ready to accept queries and extensions. Until then, the GraphQL and extension endpoints return `project_not_enrolled`.

## Install the CLI

Extension authoring and Project tooling run through the commercetools CLI and its `integration-layer` topic plugin.

```bash
npm install -g @commercetools/cli
commercetools plugins install @commercetools/cli-topic-integration-layer
```

Log in once with an API Client that has the `manage_project` scope. The CLI stores the token and reuses it for every authenticated command (`validate`, `push`, `explore`, `config`, and others):

```bash
commercetools auth login 
  --client-credentials 
  --client-id {clientId} 
  --client-secret {clientSecret} 
  --region {region} 
  --project-key {projectKey}
```

`--client-credentials` selects the client credentials authentication flow, and `--client-id` and `--client-secret` are the credentials of an API Client you create in the Merchant Center. `--region` is your Project's Region, for example `europe-west1.gcp`.

## Explore your Project's API

Introspection is unavailable on the public GraphQL endpoint, so you explore the schema locally instead of querying the edge.

`commercetools integration-layer explore` opens a browser GraphQL session against your Project's deployed edge: it reads the schema from the Commerce Integration Layer, mints a shopper session from your login, and proxies operations to the router under that session bearer. No tokens to paste and no headers to hand-edit.

```bash
commercetools integration-layer explore
```

By default, the explorer composes the core subgraph with the extension in your current directory, so fields you are editing show up before you push. To browse exactly what is live in production instead, pass `--deployed`:

```bash
commercetools integration-layer explore --deployed
```

Useful flags:

| Flag | Purpose |
| --- | --- |
| `--as user@example.com` | Run operations as a signed-in customer (prompts for the password, or set `IL_CUSTOMER_PASSWORD`) |
| `--locale de-DE --currency EUR --country DE` | Mint the session with that presentment (prices and locale-dependent fields) |
| `--port 5000` | Serve GraphiQL on a different port |
| `--session-token {token}` | Use an already-minted session bearer instead of logging in (also settable via `IL_SESSION_TOKEN`) |
| `--business-unit acme-eu --store acme-eu-de` | Select a Business Unit and Store for a B2B session (requires a signed-in customer through `--as` or `--session-token`) |

Presentment is chosen when the session is minted. To explore a different market, restart the explorer with different `--locale` / `--currency` / `--country` flags.

Operations run as an ordinary shopper, anonymous by default, or as the customer you log in with. You cannot run operations as a privileged debug identity.

### Fetch the schema

To use the schema outside the explorer, for example, for editor autocompletion, print the core shopper-facing subgraph SDL with `commercetools integration-layer schema fetch`:

```bash
commercetools integration-layer schema fetch > schema.graphql
```

## Query from your application

Every GraphQL request from a storefront or app carries a shopper [session token](/commerce-integration-layer/hosts-and-authorization.md#authorization). Mint an anonymous session from the [Identity API](/commerce-integration-layer/hosts-and-authorization.md#identity-endpoints), passing presentment so price-dependent and locale-dependent fields resolve, then send the returned token as a bearer to the GraphQL endpoint.

```bash
# 1. Mint an anonymous session (substitute your host and Project key)
TOKEN=$(curl -sX POST 
  "https://auth.integration-layer.{region}.commercetools.com/{projectKey}/main/session" 
  -H 'Content-Type: application/json' 
  -d '{"grant_type":"anonymous","locale":"en-US","currency":"USD","country":"US"}' 
  | jq -r .token)

# 2. Query the Experience API with the session token
curl -sX POST 
  "https://graphql.integration-layer.{region}.commercetools.com/{projectKey}/main/graphql" 
  -H "Authorization: Bearer $TOKEN" 
  -H 'Content-Type: application/json' 
  -d '{"query":"{ viewer { locale currency } }"}'
```

To query as a signed-in customer, use the `password` grant instead and reuse the returned token the same way. See [SessionGrantType](/commerce-integration-layer/hosts-and-authorization.md#sessiongranttype) for all grant types.

In B2B Projects, a store-scoped session can also select a [distribution channel](/commerce-integration-layer/hosts-and-authorization.md#identity-endpoints) that scopes which channel-specific prices the shopper sees.

## Scaffold an extension

`commercetools integration-layer init` scaffolds a pnpm workspace in the current directory (when it is empty) or in the path you pass. The starter includes one buildable extension under `extensions/hello-world` that adds a `hello` field to `Query`.

```bash
mkdir my-extensions && cd my-extensions
commercetools integration-layer init
pnpm install
```

A Project deploys one bundle and the root `build`, `validate`, and `push` scripts merge every package under `extensions/` into a single combined bundle. Split your code into as many `extensions/*` packages as makes sense to author, but they always ship together.

> Alternatively, start from a template in the [Commerce Integration Layer extension examples](https://github.com/commercetools/commerce-integration-layer-extensions) repository. These are ready-to-edit examples for a new query, a field on `Product`, a value computed from Commerce Integration Layer data, an external-service call, a Managed API Extension callback, and more.

## Develop locally

Before you publish, iterate on your extension with `commercetools integration-layer extension serve` (or the root `pnpm dev` script the scaffold creates). It builds your bundle, serves it as a federation subgraph, and hot-reloads when you edit `src/extension.ts`.

```bash
commercetools integration-layer extension serve
```

For the `--compose` and `--gateway` modes, how local `ctx.config` works, and how the HTTP allowlist applies while developing, see [Develop locally](/commerce-integration-layer/development/writing-schema-extensions.md#develop-locally) in Write schema extensions.

For a browser session against the deployed edge (including fields already live in production), use [`explore`](/commerce-integration-layer/development/get-started.md#explore-your-projects-api) instead.

## Validate and publish

Publish the `hello-world` extension you scaffolded to make it live on your Project. Run the publish loop from your extension directory (or the monorepo root with `--all`):

> You can publish the `hello-world` extension immediately because it doesn't require configuration or allowlisted hosts.
>
> If your extension reads a `ctx.config` value or calls an external service, you must [configure environment settings](/commerce-integration-layer/development/configure-and-deploy.md#environment-configuration-and-secrets) and [allowlist outbound hosts](/commerce-integration-layer/development/configure-and-deploy.md#outbound-http-domain-allowlist) before pushing.

```bash
commercetools integration-layer extension build       # bundle src/extension.ts
commercetools integration-layer extension validate   # local checks + compose against your Project
commercetools integration-layer extension push         # build + validate, then publish (live immediately)
```

`validate` and `push` compose your extension against your Project's live schema and reject breaking changes before anything lands. Each Project holds one bundle, so a push replaces the previous one.

Query the `hello` field it adds, using [`explore --deployed`](/commerce-integration-layer/development/get-started.md#explore-your-projects-api), to confirm the publish worked.

For the full command reference, including status, deletion, and CI flags, see [Configure and deploy](/commerce-integration-layer/development/configure-and-deploy.md). For the `typeDefs` and `resolvers` authoring model behind the extension you just published, see [Write schema extensions](/commerce-integration-layer/development/writing-schema-extensions.md).

## Further reading

- Go deeper on schema mechanics, the sandbox, configuration, and publishing in [Write schema extensions](/commerce-integration-layer/development/writing-schema-extensions.md)
- Every `commercetools integration-layer` command, with flags, in [Configure and deploy](/commerce-integration-layer/development/configure-and-deploy.md)
- How to decide whether a requirement belongs in a schema extension, a Managed API Extension, or a core platform mechanism, see [Choose an extension type](/commerce-integration-layer/extension-types.md)
- Understand entities, keys, and the directives you use when writing extensions in [GraphQL federation](/commerce-integration-layer/graphql-federation.md)

## Related pages

- [Area overview page with navigation](/commerce-integration-layer.md)
- [Next page: Write Schema Extensions](/commerce-integration-layer/development/writing-schema-extensions.md)
- [Search documentation and API specs](/search.md)