# Documentation that helps you ship

Explore our API reference, developer tools, open-source components, and exhaustive documentation. Join our vibrant community of developers and technology leaders today.

**Commerce Layer** provides the complete [transactional engine](#core-api) for modern commerce through powerful APIs. We handle the complexity of checkout, payments, inventory, orders management, and fulfillment so you can build shopping experiences that work everywhere — from traditional websites to mobile apps to [AI agents](#ready-for-the-agentic-age) making autonomous purchases. Your frontend, your CMS, your channels. Our commerce infrastructure.

## Docs-first platform

At Commerce Layer, documentation isn't an afterthought — it's our foundation, the primary interface between our engineering and yours. We treat documentation as a product with the same rigor we apply to our APIs themselves. We believe that great APIs deserve equally great docs, which is why we've invested heavily in creating comprehensive, accurate, and developer-friendly resources. Whether you're building your first integration or architecting a complex multi-market commerce system, our documentation and support are here to give you confidence that you're implementing things correctly.

This developer portal serves as your central hub for exploring everything Commerce Layer has to offer:

<table data-card-size="large" data-view="cards" data-full-width="false"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><h4><i class="fa-cart-circle-check">:cart-circle-check:</i></h4></td><td><strong>Core API</strong></td><td>The complete transactional commerce engine with hundreds of fast and secure REST API endpoints. Manage checkout, payments, inventory, orders, and fulfillment across any channel.</td><td><a href="/pages/7ItInN9YOpYIjaMumBjl#core-api">/pages/7ItInN9YOpYIjaMumBjl#core-api</a></td><td></td></tr><tr><td><h4><i class="fa-window-restore">:window-restore:</i></h4></td><td><strong>Pre-built applications</strong></td><td>Production-ready micro frontends you can deploy instantly or use as reference implementations. From hosted checkout and cart to customer portals — integrate with a link or fork and customize the code.</td><td><a href="/pages/7ItInN9YOpYIjaMumBjl#pre-built-applications">/pages/7ItInN9YOpYIjaMumBjl#pre-built-applications</a></td><td></td></tr><tr><td><h4><i class="fa-screwdriver-wrench">:screwdriver-wrench:</i></h4></td><td><strong>Developer tools</strong></td><td>SDKs, CLI, component libraries, and integrations for your entire workflow. Work in JavaScript, React, or the terminal — use Postman collections, OpenAPI schemas, or connect via Zapier for no-code automation.</td><td><a href="/pages/7ItInN9YOpYIjaMumBjl#developer-tools">/pages/7ItInN9YOpYIjaMumBjl#developer-tools</a></td><td></td></tr><tr><td><h4><i class="fa-chart-pie">:chart-pie:</i></h4></td><td><strong>Advanced APIs</strong></td><td>Specialized APIs that extend Core functionality with analytics and provisioning capabilities. Query commerce metrics directly, build custom dashboards, and automate team management across organizations.</td><td><a href="/pages/7ItInN9YOpYIjaMumBjl#advanced-apis">/pages/7ItInN9YOpYIjaMumBjl#advanced-apis</a></td><td></td></tr></tbody></table>

{% hint style="success" icon="user-group" %}
Want to get involved? Explore [our ecosystem](#build-with-us) to contribute code, stay updated, and connect with fellow developers.
{% endhint %}

## Ready for the agentic age

As a unified commerce engine that powers any transaction, anywhere, built API-first since day one, Commerce Layer is ready by design to be the enabler of a new era of interactions where AI agents don't just recommend products — they research, compare, and complete purchases autonomously on behalf of users. Enter [agentic commerce](https://commercelayer.io/agentic-commerce).

Our architecture enables AI agents to execute every commerce action programmatically. But having accessible APIs is only half the equation for agentic commerce. AI agents also need to understand how to use those APIs correctly, which means they need access to documentation in formats they can effectively consume and reason about. In short terms, documentation must also be AI-ready. That's why Commerce Layer docs follow close behind, offering some features you can leverage out of the box to ensure that AI systems can retrieve and provide accurate, contextual responses in real-time.&#x20;

### LLM-friendly <a href="#llm-friendly" id="llm-friendly"></a>

**Large Language Models** are becoming increasingly important for information retrieval and knowledge assistance. To make Commerce Layer APIs documentation content available in [text-based formats](https://llmstxt.org/) that are easier for LLMs to process, ingest, and work with, you can leverage the following `llms.txt` files.

* [Index](https://docs.commercelayer.io/llms.txt) — contains an index of all the page URLs and titles of our API docs sites, providing a comprehensive list of all available markdown-formatted pages:

```
https://docs.commercelayer.io/llms.txt
```

* [Full content](https://docs.commercelayer.io/llms-full.txt) — contains the full content of our API docs sites in one file that can be passed to LLMs as context:

```
https://docs.commercelayer.io/llms-full.txt
```

{% hint style="info" icon="circle-info" %}
On top of that, all of the pages of Commerce Layer docs are automatically available as markdown files. If you add the `.md` extension to any page, you will see the content of that page rendered in markdown which you can pass to an LLM for more efficient processing than an HTML file.
{% endhint %}

### MCP server <a href="#mcp-server" id="mcp-server"></a>

**Model Context Protocol** gives AI tools a structured way to discover and retrieve your docs as resources — no scraping required. To allow AI assistants to access Commerce Layer APIs documentation content directly, making it easy for tools like [Claude Desktop](https://code.claude.com/docs/en/mcp), [Cursor](https://cursor.com/docs/context/mcp), and [VS Code](https://code.visualstudio.com/docs/copilot/customization/mcp-servers) extensions to answer questions using the docs, we expose via `HTTP` an MCP server at the following URL:

```
https://docs.commercelayer.io/~gitbook/mcp
```

{% hint style="warning" %}
Visiting the URL above in your browser will result in an error. Instead, you can share this with tools that can make HTTP requests, like LLMs or IDEs.
{% endhint %}

## Core API

Build comprehensive commerce experiences with our API-first platform. Access hundreds of endpoints and webhooks to add global shopping capabilities — from dynamic pricing and distributed inventory to localized payments and intelligent order management — to any digital experience.

<table data-view="cards" data-full-width="false"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><h4><i class="fa-rocket-launch">:rocket-launch:</i></h4></td><td><strong>Getting started</strong></td><td>Learn how to set up your Commerce Layer organization and place your first order. Follow our comprehensive onboarding guide to understand the data model, configure your environment, and start building quickly.</td><td><a href="/spaces/-LgByaSP8eKjad-MIuHE">/spaces/-LgByaSP8eKjad-MIuHE</a></td><td></td></tr><tr><td><h4><i class="fa-book-open-lines">:book-open-lines:</i></h4></td><td><strong>API reference</strong></td><td>Explore our complete REST API with detailed documentation for all 100+ endpoints. Browse resource structures, discover 400+ available CRUD operations, and understand authentication patterns for every use case.</td><td><a href="/spaces/RWJeylueWkzLadK710XZ">/spaces/RWJeylueWkzLadK710XZ</a></td><td></td></tr><tr><td><h4><i class="fa-lightbulb">:lightbulb:</i></h4></td><td><strong>How-tos</strong></td><td>ccess step-by-step tutorials and practical examples covering common commerce scenarios. Learn best practices for implementing features like multi-currency pricing, promotions, and subscription management.</td><td><a href="/spaces/-Lk-ezuDClaMavTqnRi0">/spaces/-Lk-ezuDClaMavTqnRi0</a></td><td></td></tr><tr><td><h4><i class="fa-gear">:gear:</i></h4></td><td><strong>Rules engine</strong></td><td>Build flexible business logic tailored to your needs. Create dynamic pricing strategies, complex promotions, and conditional workflows using JSON-based rules with intuitive visual builders available.</td><td><a href="/spaces/hiqD9AvrD8A8IPj7QXPv">/spaces/hiqD9AvrD8A8IPj7QXPv</a></td><td></td></tr><tr><td><h4><i class="fa-signal-stream">:signal-stream:</i></h4></td><td><strong>Event stream</strong></td><td>Stay synchronized with real-time resource changes using Server-Sent Events. Our Stream Hub provides enterprise customers with instant updates for orders, inventory, and all API resources without polling.</td><td><a href="/spaces/-LgByaSP8eKjad-MIuHE/pages/X1sMys17Ix4VO4Pv1Kh9">/spaces/-LgByaSP8eKjad-MIuHE/pages/X1sMys17Ix4VO4Pv1Kh9</a></td><td></td></tr><tr><td><h4><i class="fa-diagram-project">:diagram-project:</i></h4></td><td><strong>Data model</strong></td><td>Understand how Commerce Layer structures commerce data through comprehensive E-R diagrams. Explore resource relationships, learn dependency patterns, and see how objects connect across the system.</td><td><a href="/spaces/lDfS8CZ2kCfiwsAPFyWM">/spaces/lDfS8CZ2kCfiwsAPFyWM</a></td><td></td></tr></tbody></table>

## Pre-built applications

Accelerate development with our production-ready commerce micro frontends. These open-source applications integrate seamlessly into your website with a simple link or serve as reference implementations for custom builds. Focus on your unique value while we handle core commerce functionality.

<table data-view="cards" data-full-width="false"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><h4><i class="fa-cart-shopping">:cart-shopping:</i></h4></td><td><strong>Cart</strong></td><td>Implement a full-featured shopping cart with real-time inventory checks and automatic price updates. Customers can manage quantities, apply promo codes, and see personalized pricing across all markets.</td><td><a href="https://github.com/commercelayer/mfe-cart">https://github.com/commercelayer/mfe-cart</a></td><td></td></tr><tr><td><h4><i class="fa-credit-card">:credit-card:</i></h4></td><td><strong>Checkout</strong></td><td>Deploy a PCI-compliant, PSD2-ready checkout flow powered by Commerce Layer APIs. Support multiple payment methods, handle tax calculations, and enable seamless multi-market transactions out of the box.</td><td><a href="https://github.com/commercelayer/mfe-checkout">https://github.com/commercelayer/mfe-checkout</a></td><td></td></tr><tr><td><h4><i class="fa-circle-user">:circle-user:</i></h4></td><td><strong>My account</strong></td><td>Give customers a complete self-service portal to manage order history, saved addresses, and payment methods. Enable profile updates, track shipments, and handle returns without custom development.</td><td><a href="https://github.com/commercelayer/mfe-my-account">https://github.com/commercelayer/mfe-my-account</a></td><td></td></tr><tr><td><h4><i class="fa-user-viewfinder">:user-viewfinder:</i></h4></td><td><strong>Identity</strong></td><td>Streamline user authentication and account management with our hosted identity solution. Handle customer registration, password resets, and secure login flows while maintaining full brand consistency.</td><td><a href="https://github.com/commercelayer/mfe-identity">https://github.com/commercelayer/mfe-identity</a></td><td></td></tr><tr><td><h4><i class="fa-browsers">:browsers:</i></h4></td><td><strong>Microstores</strong></td><td>Launch lightweight commerce experiences for specific campaigns, collections, or markets. Create focused shopping environments that share your main store's inventory and backend without full site development.</td><td><a href="https://github.com/commercelayer/mfe-microstore">https://github.com/commercelayer/mfe-microstore</a></td><td></td></tr><tr><td><h4><i class="fa-browser">:browser:</i></h4></td><td><strong>Demo store</strong></td><td>Explore a fully functional static ecommerce site built with Commerce Layer, complete with SSR capabilities. Use it as a starting template, reference architecture, or learning resource for your projects.</td><td><a href="https://github.com/commercelayer/demo-store">https://github.com/commercelayer/demo-store</a></td><td></td></tr></tbody></table>

## Developer tools

Build fast and stay productive with our comprehensive developer toolkit. From SDKs and CLI tools to component libraries and integrations, we provide everything you need for modern development. Manage resources, automate workflows, and integrate Commerce Layer using your preferred tools and frameworks.

<table data-view="cards" data-full-width="false"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><h4><i class="fa-key">:key:</i></h4></td><td><strong>JS Auth</strong></td><td>Simplify authentication flows with our lightweight JavaScript library. Handle OAuth2 tokens, manage refresh logic, and secure API calls across browser, server, or edge environments with minimal code.</td><td><a href="https://github.com/commercelayer/commercelayer-js-auth">https://github.com/commercelayer/commercelayer-js-auth</a></td><td></td></tr><tr><td><h4><i class="fa-gear-code">:gear-code:</i></h4></td><td><strong>JS SDK</strong></td><td>Interact with Commerce Layer APIs using our modern JavaScript SDK with full TypeScript support. Features tree-shaking for optimal bundle sizes, intuitive resource methods, and automatic token management.</td><td><a href="https://github.com/commercelayer/commercelayer-sdk">https://github.com/commercelayer/commercelayer-sdk</a></td><td></td></tr><tr><td><h4><i class="fa-eye-dropper">:eye-dropper:</i></h4></td><td><strong>Drop-in library</strong></td><td>Transform static HTML pages into enterprise-grade commerce sites with simple web components. Add prices, availability, cart functionality, and checkout to any page using only HTML attributes — no frameworks required.</td><td><a href="https://commercelayer.github.io/drop-in.js/">https://commercelayer.github.io/drop-in.js/</a></td><td></td></tr><tr><td><h4><i class="fa-terminal">:terminal:</i></h4></td><td><strong>CLI</strong></td><td>Manage your Commerce Layer operations directly from the terminal. Import data, export reports, create resources, generate checkout links, and automate complex workflows without leaving the command line.</td><td><a href="https://github.com/commercelayer/commercelayer-cli">https://github.com/commercelayer/commercelayer-cli</a></td><td></td></tr><tr><td><h4><i class="fa-react">:react:</i></h4></td><td><strong>React components</strong></td><td>Build custom commerce UIs with our composable React component library. Create flexible, interactive shopping experiences while maintaining full control over styling and behavior in your React applications.</td><td><a href="https://commercelayer.github.io/commercelayer-react-components/">https://commercelayer.github.io/commercelayer-react-components/</a></td><td></td></tr><tr><td><h4><i class="fa-shapes">:shapes:</i></h4></td><td><strong>App elements</strong></td><td>Replicate Commerce Layer's Dashboard design system in your custom applications. This React component library provides pre-built UI elements that match our interface, ensuring consistent user experiences.</td><td><a href="https://commercelayer.github.io/app-elements">https://commercelayer.github.io/app-elements</a></td><td></td></tr><tr><td><h4><i class="fa-list-tree">:list-tree:</i></h4></td><td><strong>OpenAPI schema</strong></td><td>Generate client libraries, validate requests, and build tooling using our complete OpenAPI specification. Access machine-readable API definitions to automate integration and streamline developer workflows.</td><td><a href="https://data.commercelayer.app/schemas/openapi.json">https://data.commercelayer.app/schemas/openapi.json</a></td><td></td></tr><tr><td><h4><i class="fa-bolt-lightning">:bolt-lightning:</i></h4></td><td><strong>Zapier app</strong></td><td>Connect Commerce Layer with 5,000+ third-party services through Zapier. Build no-code automation workflows for order processing, inventory updates, customer notifications, and business operations in minutes.</td><td><a href="https://zapier.com/apps/commerce-layer/integrations">https://zapier.com/apps/commerce-layer/integrations</a></td><td></td></tr><tr><td><h4><i class="fa-user-astronaut">:user-astronaut:</i></h4></td><td><strong>Postman collections</strong></td><td>Import all Commerce Layer API endpoints into Postman with a single click. Test API calls, explore resources, and debug integrations using our maintained workspace with pre-configured request examples.</td><td><a href="https://www.postman.com/commercelayer">https://www.postman.com/commercelayer</a></td><td></td></tr></tbody></table>

## Advanced APIs

Extend your implementation with modular APIs for business analytics, operational insights, and flexible integration. These specialized APIs work alongside [Core API](#core-api) to provide deeper control over provisioning, enable custom reporting, and unlock programmatic account management across your organization.

<table data-card-size="large" data-view="cards" data-full-width="false"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><h4><i class="fa-chart-line-up">:chart-line-up:</i></h4></td><td><strong>Metrics API</strong></td><td>Extract powerful commerce insights through advanced analytics queries. Calculate conversion rates, track customer behavior, and build custom dashboards with KPI measurements on-demand — no external BI tools needed.</td><td><a href="/spaces/ASSiAvbL4nFnkl8plQy2">/spaces/ASSiAvbL4nFnkl8plQy2</a></td><td></td></tr><tr><td><h4><i class="fa-user">:user:</i></h4></td><td><strong>Provisioning API</strong></td><td>Automate account management and access control programmatically. Create team accounts, assign permissions, generate API credentials, and streamline user onboarding workflows across multiple organizations.</td><td><a href="/spaces/xrdVVavnnBMHRCqrLp1y">/spaces/xrdVVavnnBMHRCqrLp1y</a></td><td></td></tr></tbody></table>

## Build with us

Commerce Layer is built in the open, by developers, for developers — because we believe transparency and collaboration create better software. Whether you want to contribute code, stay informed about new features, or connect with our community, we're here to support your journey. Explore our open-source projects, track updates, and join the conversation.

<table data-view="cards" data-full-width="false"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><h4><i class="fa-github">:github:</i></h4></td><td><strong>GitHub</strong></td><td>Every tool, library, and micro frontend we build is open source. Browse our repositories, inspect the code, submit pull requests, and contribute improvements. Your inputs help shape Commerce Layer's future.</td><td><a href="https://github.com/commercelayer">https://github.com/commercelayer</a></td><td></td></tr><tr><td><h4><i class="fa-calendar">:calendar:</i></h4></td><td><strong>Changelog</strong></td><td>Track every update, feature release, and improvement across all Commerce Layer products. Get detailed release notes for all our APIs, developer tools, and open-source projects — never miss what's new or breaking.</td><td><a href="/spaces/8DjTu5pfPzXTm6rzaAmr">/spaces/8DjTu5pfPzXTm6rzaAmr</a></td><td></td></tr><tr><td><h4><i class="fa-discord">:discord:</i></h4></td><td><strong>Discord</strong></td><td>Get your invite and connect with fellow developers building on Commerce Layer. Get help from our team, share solutions with the community, discuss best practices, and stay informed about upcoming features and beta programs.</td><td><a href="https://discord.com/invite/commercelayer">https://discord.com/invite/commercelayer</a></td><td></td></tr></tbody></table>


# Made to be loved by devs

Our developer portal makes it easy to integrate with Commerce Layer. Explore guides, examples, resources, and references. Reference our production-ready apps and tools. Start building right now.

Commerce Layer provides the complete [transactional engine](#core-api) for modern commerce through powerful APIs. We handle the complexity of checkout, payments, inventory, orders management, and fulfillment so you can build shopping experiences that work everywhere — from traditional websites to mobile apps to [AI agents](#ready-for-the-agentic-age) making autonomous purchases. Your frontend, your CMS, your channels. Our commerce infrastructure.

## Docs-first platform

For an API-first platform, documentation isn't an afterthought — it's the primary interface between our engineering and yours. We treat documentation as a product with the same rigor we apply to our APIs themselves. Every endpoint is documented completely, every integration pattern is explained clearly, and every edge case is addressed honestly. We know that incomplete or inaccurate documentation doesn't just slow developers down — it erodes trust and creates technical debt in your integrations. That's why our documentation is comprehensive, maintained continuously, and designed to answer both "how do I do this" and "why does this work this way." Whether you're building your first integration or architecting a complex multi-market commerce system, our documentation and support are here to give you confidence that you're implementing things correctly.

This developer portal is the first entry-point to start navigating our docs. Explore our API reference, applications, developer tools, open-source components, and exhaustive documentation. [Monitor our changelog](https://docs.commercelayer.io/changelog/) regularly to stay current with platform evolution and planning for upcoming changes. [Join our vibrant community](#join-our-community) of developers and technology leaders today.

<a href="/spaces/8DjTu5pfPzXTm6rzaAmr" class="button primary" data-icon="bell-on">Check for updates</a> <a href="https://discord.gg/commercelayer" class="button secondary" data-icon="discord">Ask your peers</a>

## Ready for the agentic age

As a unified commerce engine that powers any transaction, anywhere, built API-first since day one, Commerce Layer is ready by design to be the enabler of a new era of interactions — [agentic commerce](https://commercelayer.io/agentic-commerce).

Every commerce operation in Commerce Layer is accessible through clean, well-documented APIs that AI agents can call directly. But having accessible APIs is only half the equation for agentic commerce. AI agents also need to understand how to use those APIs correctly, which means they need access to documentation in formats they can effectively consume and reason about. That's why Commerce Layer docs follow close behind, offering some features you can leverage out of the box to ensure that AI systems can retrieve and provide accurate, contextual responses about Commerce Layer APIs.&#x20;

### LLM-friendly <a href="#llm-friendly" id="llm-friendly"></a>

**Large Language Models** are becoming increasingly important for information retrieval and knowledge assistance. To make Commerce Layer APIs documentation content available in [text-based formats](https://llmstxt.org/) that are easier for LLMs to process, ingest, and work with, you can leverage the following `llms.txt` files.

* [Index](https://docs.commercelayer.io/llms.txt) — contains an index of all the page URLs and titles of our API docs sites, providing a comprehensive list of all available markdown-formatted pages:

```
https://docs.commercelayer.io/llms.txt
```

* [Full content](https://docs.commercelayer.io/llms-full.txt) — contains the full content of our API docs sites in one file that can be passed to LLMs as context:

```
https://docs.commercelayer.io/llms-full.txt
```

### MCP server <a href="#mcp-server" id="mcp-server"></a>

**Model Context Protocol** gives AI tools a structured way to discover and retrieve your docs as resources — no scraping required. To allow AI assistants to access Commerce Layer APIs documentation content directly, making it easy for tools like [Claude Desktop](https://code.claude.com/docs/en/mcp), [Cursor](https://cursor.com/docs/context/mcp), and [VS Code](https://code.visualstudio.com/docs/copilot/customization/mcp-servers) extensions to answer questions using the docs, we expose via `HTTP` an MCP server at the following URL:

```
https://docs.commercelayer.io/~gitbook/mcp
```

{% hint style="warning" %}
Visiting the URL above in your browser will result in an error. Instead, you can share this with tools that can make HTTP requests, like LLMs or IDEs.
{% endhint %}

***

## Get started your way

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><h4><i class="fa-gear-code">:gear-code:</i></h4></td><td><strong>Build your first integration</strong></td><td>If you're ready to start integrating Commerce Layer into your application, begin with our <a href="/spaces/-LgByaSP8eKjad-MIuHE/pages/-LisBCOeYkUOUUdRaQwW">Core API</a> getting started guide. You'll learn how authentication works, make your first API calls, and understand the fundamental concepts. In no time, you'll have created your first order programmatically and understand how our API architecture works. Most developers start here because it gives you the foundation for everything else you'll build.</td><td></td><td></td></tr><tr><td><h4><i class="fa-screwdriver-wrench">:screwdriver-wrench:</i></h4></td><td><strong>Explore with ready-made tools</strong></td><td>Want to experience Commerce Layer's capabilities before writing backend code? Start with our <a href="https://github.com/commercelayer/commercelayer-cli">CLI</a> to explore resources from your terminal, try our <a href="https://commercelayer.github.io/commercelayer-react-components/">React Components</a> to see how shopping interfaces work, or embed our <a href="https://commercelayer.github.io/drop-in.js/">Drop-in</a> library to add a complete checkout experience to any website in minutes. These tools let you see what's possible and often become permanent parts of your implementation, not just learning exercises.</td><td><a href="https://github.com/commercelayer/commercelayer-cli">https://github.com/commercelayer/commercelayer-cli</a></td><td></td></tr><tr><td><h4><i class="fa-vector-polygon">:vector-polygon:</i></h4></td><td><strong>Understand the architecture</strong></td><td>If you're evaluating whether Commerce Layer fits your technical requirements, start with our <a href="https://commercelayer.io/docs/data-model/">data model</a> to understand how resources relate to each other, then explore our <a href="/spaces/RWJeylueWkzLadK710XZ">API reference</a> to see the breadth of capabilities available. This approach works well for technical decision-makers who need to assess scalability, flexibility, and integration patterns before committing to implementation work.</td><td><a href="/spaces/RWJeylueWkzLadK710XZ">/spaces/RWJeylueWkzLadK710XZ</a></td><td></td></tr></tbody></table>

## Core API

The Core API is the complete commerce engine that powers everything from simple checkout flows to complex multi-market operations. It manages your entire product catalog with SKUs and prices, handles inventory across multiple stock locations, processes orders with sophisticated routing logic, integrates with payment gateways worldwide, calculates taxes based on jurisdiction rules, and coordinates shipments with carriers. This API is designed for complexity as a first principle — multi-market, multi-currency, and end-to-end-order management scenarios are built into the foundation, not added ex post. Most developers spend the majority of their time working with the Core API because it handles the fundamental commerce operations that every implementation needs.

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><h4><i class="fa-rocket">:rocket:</i></h4></td><td><strong>Getting started</strong></td><td>Kick off your integration with step-by-step guides, essential concepts, and practical examples. Learn how Commerce Layer works, explore core concepts, and start building your first end-to-end commerce workflow.</td><td><a href="/spaces/-LgByaSP8eKjad-MIuHE">/spaces/-LgByaSP8eKjad-MIuHE</a></td><td></td></tr><tr><td><h4><i class="fa-list-tree">:list-tree:</i></h4></td><td><strong>API reference</strong></td><td>A comprehensive list of all Commerce Layer's core 120+ resources. Check the structure of the objects and the allowed CRUD operations you can perform on each one of the 400+ endpoints.</td><td><a href="/spaces/RWJeylueWkzLadK710XZ">/spaces/RWJeylueWkzLadK710XZ</a></td><td></td></tr><tr><td><h4><i class="fa-book">:book:</i></h4></td><td><strong>How-tos</strong></td><td>Step-by-step tutorials and practical guides covering common ecommerce tasks, from carts and checkout to inventory, payments, and more. Learn how to implement real workflows using Commerce Layer’s core features.</td><td><a href="/spaces/-Lk-ezuDClaMavTqnRi0">/spaces/-Lk-ezuDClaMavTqnRi0</a></td><td></td></tr><tr><td><h4><i class="fa-gift">:gift:</i></h4></td><td><strong>Rules engine</strong></td><td>Create sophisticated business logic with our flexible Domain-Specific Language. Build complex promotional campaigns, dynamic pricing rules, automated workflows, or any other custom logic without writing any code.</td><td><a href="/spaces/hiqD9AvrD8A8IPj7QXPv">/spaces/hiqD9AvrD8A8IPj7QXPv</a></td><td></td></tr><tr><td><h4><i class="fa-signal-stream">:signal-stream:</i></h4></td><td><strong>Event stream</strong></td><td>Stay synchronized with real-time data changes through Server-Sent Events. Receive instant notifications when orders, inventory, or customer data updates occur with historical event replay capabilities.</td><td><a href="/spaces/-LgByaSP8eKjad-MIuHE/pages/X1sMys17Ix4VO4Pv1Kh9">/spaces/-LgByaSP8eKjad-MIuHE/pages/X1sMys17Ix4VO4Pv1Kh9</a></td><td></td></tr><tr><td><h4><i class="fa-diagram-project">:diagram-project:</i></h4></td><td><strong>Data model</strong></td><td>Discover the core data structure of Commerce Layer and learn how markets, SKUs, price lists, inventory, customers, and orders relate. Explore the underlying model, entity relationships, and how to configure your commerce setup.</td><td></td><td></td></tr></tbody></table>

## Pre-built applications

Accelerate your time-to-market with fully branded, production-ready commerce apps. Integrate them into any website with a single link or use them as open-source foundations for your projects.

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><h4><i class="fa-cart-shopping">:cart-shopping:</i></h4></td><td><strong>Cart</strong></td><td>A React‑based shopping cart application that you can integrate with just a single link or use as an open-source reference for your projects.</td><td><a href="/spaces/-LgByaSP8eKjad-MIuHE">/spaces/-LgByaSP8eKjad-MIuHE</a></td><td></td></tr><tr><td><h4><i class="fa-credit-card">:credit-card:</i></h4></td><td><strong>Checkout</strong></td><td>A React‑based checkout application that you can integrate with just a single link or use as an open-source reference for your projects.</td><td><a href="/spaces/RWJeylueWkzLadK710XZ">/spaces/RWJeylueWkzLadK710XZ</a></td><td></td></tr><tr><td><h4><i class="fa-circle-user">:circle-user:</i></h4></td><td><strong>My account</strong></td><td>A React‑based customer portal application with personal account information and management that you can integrate with just a single link or use as an open-source reference for your projects.</td><td><a href="/spaces/-Lk-ezuDClaMavTqnRi0">/spaces/-Lk-ezuDClaMavTqnRi0</a></td><td></td></tr><tr><td><h4><i class="fa-right-to-bracket">:right-to-bracket:</i></h4></td><td><strong>Identity</strong></td><td>A React‑based application handling customer login and sign-up that you can integrate with just a single link or use as an open-source reference for your projects.</td><td><a href="/spaces/hiqD9AvrD8A8IPj7QXPv">/spaces/hiqD9AvrD8A8IPj7QXPv</a></td><td></td></tr><tr><td><h4><i class="fa-store">:store:</i></h4></td><td><strong>Microstore</strong></td><td>A React‑based application that provides you with a production-ready, self-contained store. Each microstore will be accessible at a unique URL and configurable via URL query strings, with no development required.</td><td><a href="/spaces/-LgByaSP8eKjad-MIuHE/pages/X1sMys17Ix4VO4Pv1Kh9">/spaces/-LgByaSP8eKjad-MIuHE/pages/X1sMys17Ix4VO4Pv1Kh9</a></td><td></td></tr><tr><td><h4><i class="fa-laptop-code">:laptop-code:</i></h4></td><td><strong>Demo store</strong></td><td>A completely static ecommerce solution powered by Commerce Layer. The store is fully featured and operational, with no 3rd-party services required. You can use it as a template and easily tailor your own.</td><td><a href="https://commercelayer.io/docs/data-model/">https://commercelayer.io/docs/data-model/</a></td><td></td></tr></tbody></table>

## Get started your way

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><h4><i class="fa-rocket">:rocket:</i></h4></td><td><strong>Build your first integration</strong></td><td>If you're ready to start integrating Commerce Layer into your application, begin with our <a href="/spaces/-LgByaSP8eKjad-MIuHE/pages/-LisBCOeYkUOUUdRaQwW">Core API</a> getting started guide. You'll learn how authentication works, make your first API calls, and understand the fundamental concepts. In no time, you'll have created your first order programmatically and understand how our API architecture works. Most developers start here because it gives you the foundation for everything else you'll build.</td><td></td><td></td></tr><tr><td><h4><i class="fa-screwdriver-wrench">:screwdriver-wrench:</i></h4></td><td><strong>Explore with ready-made tools</strong></td><td>Want to experience Commerce Layer's capabilities before writing backend code? Start with our <a href="https://github.com/commercelayer/commercelayer-cli">CLI</a> to explore resources from your terminal, try our <a href="https://commercelayer.github.io/commercelayer-react-components/">React Components</a> to see how shopping interfaces work, or embed our <a href="https://commercelayer.github.io/drop-in.js/">Drop-in</a> library to add a complete checkout experience to any website in minutes. These tools let you see what's possible and often become permanent parts of your implementation, not just learning exercises.</td><td><a href="https://github.com/commercelayer/commercelayer-cli">https://github.com/commercelayer/commercelayer-cli</a></td><td></td></tr><tr><td><h4><i class="fa-diagram-project">:diagram-project:</i></h4></td><td><strong>Understand the architecture</strong></td><td>If you're evaluating whether Commerce Layer fits your technical requirements, start with our <a href="https://commercelayer.io/docs/data-model/">data model</a> to understand how resources relate to each other, then explore our <a href="/spaces/RWJeylueWkzLadK710XZ">API reference</a> to see the breadth of capabilities available. This approach works well for technical decision-makers who need to assess scalability, flexibility, and integration patterns before committing to implementation work.</td><td><a href="/spaces/RWJeylueWkzLadK710XZ">/spaces/RWJeylueWkzLadK710XZ</a></td><td></td></tr></tbody></table>

## Join our community

Thousands of developers build on Commerce Layer every day, and many of them share knowledge, help troubleshoot integration challenges, discuss architecture decisions, and showcase what they're building in [our Discord community](https://discord.gg/commercelayer). This is where you'll find real-time help from both Commerce Layer team members and experienced developers who have solved similar problems. Whether you're stuck on a specific API behavior, evaluating different implementation approaches, or just want to connect with other people building the future of commerce, Discord is where the conversation happens. Join us there.

<a href="https://discord.gg/commercelayer" class="button primary" data-icon="discord">Get your invite</a> <a class="button secondary"></a>

<h2 align="center">Developer platform template</h2>

<p align="center">Welcome to your team’s new developer platform</p>

<p align="center"><a href="http://app.gitbook.com/join" class="button primary">Sign up</a> <a href="http://app.gitbook.com/join" class="button secondary">Log in</a></p>

{% columns %}
{% column %}

### Get started in 5 minutes

Setting up your first API call should be the easiest part of getting started. With clear endpoints, copy-paste-ready examples, and quick authentication, you’ll be up and running in minutes—not hours.

No guesswork, no complexity—just your first successful call, fast.

<a href="https://template.gitbook.com/space-product-docs" class="button primary" data-icon="rocket-launch">Get started</a> <a href="https://template.gitbook.com/space-api-reference" class="button secondary" data-icon="terminal">API reference</a>
{% endcolumn %}

{% column %}
{% code title="index.js" overflow="wrap" %}

```javascript
// Import the SDK
import ExampleAPI from "example-api";

// Initialize the client
const client = new ExampleAPI({ apiKey: "YOUR_API_KEY" });

// Send your first message
const response = await client.messages.send({
  message: "Hello, world!"
});

```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

{% columns %}
{% column %}

<figure><img src="https://gitbookio.github.io/onboarding-template-images/placeholder.png" alt=""><figcaption></figcaption></figure>
{% endcolumn %}

{% column %}

### Learn more about the developer platform

Read guides, watch tutorials, and learn more about working with the developer platform and integrating it with your own stack.

<a href="https://template.gitbook.com/space-help-center" class="button primary" data-icon="book-open">Guides</a> <a href="https://template.gitbook.com/space-product-docs" class="button secondary" data-icon="book">Documentation</a>
{% endcolumn %}
{% endcolumns %}

<h2 align="center">Join a community of over 3,000 developers</h2>

<p align="center">Join our Discord community or create your first PR in just a few steps.</p>

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th></th><th></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><h4><i class="fa-discord">:discord:</i></h4></td><td><strong>Discord community</strong></td><td>Join our Discord community to post questions, get help, and share resources with over 3,000 like-minded developers.</td><td><a href="https://www.gitbook.com/" class="button secondary">Join Discord</a></td><td></td></tr><tr><td><h4><i class="fa-github">:github:</i></h4></td><td><strong>GitHub</strong></td><td>Our product is 100% open source and built by developers just like you. Head to our GitHub repository to learn how to submit your first PR.</td><td><a href="https://www.gitbook.com/" class="button secondary">Submit a PR</a></td><td></td></tr></tbody></table>


# Welcome to Core API

How to get started with Commerce Layer Core API and set up your first organization

Commerce Layer Core API is our foundational REST API that powers transactional commerce for international brands. It provides everything you need to make any digital experience shoppable — from multi-currency prices and distributed inventory to localized payment gateways, promotions, orders, subscriptions, and more.

{% hint style="success" %}
**Commerce Layer is free for developers, and it will be forever.** So the best way to get started is to [create an account](https://dashboard.commercelayer.io/sign_up) and try the API.
{% endhint %}

Once you signed up, you have two options to configure your environment:

* Leverage the [setup wizard](/core/onboarding/guided-setup) available in the Dashboard UI. This is the fastest way to add a minimum viable configuration to your environment and be ready to place your first order in a short time.
* Manually create all the required resources in the correct order (based on their mutual relationships) and [configure your organization step-by-step](/core/onboarding/manual-configuration). This could take a while longer, but it's a good opportunity to dig deeper into how Commerce Layer works, learn more about how its data model is structured, and get to grip with a powerful tool like the [Commerce Layer CLI](https://github.com/commercelayer/commercelayer-cli) that will enable you to complete the whole process without leaving the command line.

Take your pick, and let's get started!


# Guided setup

Sign up for free and set up your organization

As soon as you [sign up for free](https://dashboard.commercelayer.io/sign_up) and your account is successfully confirmed, you will be prompted to [create your first organization](#create-an-organization). To begin receiving orders and making sales through Commerce Layer, you need to configure it so that it meets some minimum requirements. A simple wizard on the Dashboard UI will guide you through the necessary steps to configure it.

The wizard is split into three main sections:

1. [Creating a merchant, a market and defining your business model](#create-a-market)
2. [Setting up shipments and payments](#set-up-shipping-and-payments)
3. [Adding products, stock, and prices](#add-some-products)

## Create an organization

To create your first sample organization all you need to do is choose a meaningful name for it and select the region where your data will be stored.

{% hint style="warning" %}
Once the organization is created, the chosen data storage location cannot be changed anymore.
{% endhint %}

![](/files/H2rNkMDlkJnEIJ7Fm80m)

{% hint style="info" %}
If — for whatever reason — you need to delete one or more of the organizations you created, please ask the organization owner to reach out to our support team and send a specific request to [support@commercelayer.io ](mailto:support@commercelayer.io)specifying the list of the organization slug you want to be deleted.
{% endhint %}

## Create a market

For starters, you need a market where to sell your products. To create a market you must first define your business model by setting up:

* A [merchant](/core-api-reference/merchants) — the seller or owner of each market in your organization. You need to provide a name and your company address.
* A [stock location](/core-api-reference/stock_locations) — the physical (or virtual) warehouse from where to ship your products and/or to where to return them. You need to provide a name, an address, and an optional code. From here you can also choose the shipping label format.
* An [inventory model](/core-api-reference/inventory_models) — from here you can choose the inventory strategy, set up some parameters related to stock reservations and stock transfers, and specify how you want to manage the stock (e.g. manually).
* A [price list](/core-api-reference/price_lists) — a container for all the prices of your products in a specific currency. Here is where you also need to specify whether the prices in the price lists will include taxes (e.g. B2C VAT) or not (e.g. B2B VAT, sales taxes).

The setup wizard will guide you through all the necessary steps to create all the resources above and your progress will be displayed in the Dashboard UI:

![](/files/LmRTEoWuHQut8kgayG8L)

Now you can use those resources to create your first market. You can optionally specify a market code and, at a later time, connect other optional resources such as:

* A [customer group](/core-api-reference/customer_groups) — to make the market private
* A [subscription model](/core-api-reference/subscription_models) — to manage order subscriptions.
* A [tax calculator](/core-api-reference/tax_calculators) — to calculate taxes for the market's orders
* A [geocoder](/core-api-reference/geocoders) — to automatically geocode addresses

From here you can also manage some market-specific features (e.g. [prices](/core/external-resources/external-prices) or [order validation](/core/external-resources/external-order-validation)) using an external service.

## Set up shipping and payments

### Shipping

To be able to ship your product to your customers,  you need to configure one or more shipping methods. To create a shipping method you must first set up:

* A [shipping category](/core-api-reference/shipping_categories) — you need to provide the category name and an optional code.
* A [shipping zone](/core-api-reference/shipping_zones) —  you need to provide a name for the zone and country code / state code / ZIP code based RegEx that defines it.

The setup wizard will guide you through all the necessary steps to create all the resources above and your progress will be displayed in the Dashboard UI:

![](/files/14K8dpm0aDTqnR1pJa6G)

Now you can create a [shipping method](/core-api-reference/shipping_methods) and optionally restrict it to the [previously created market](#create-a-market) or to a specific currency. Here you can also:

* Decide how to manage the cost of the shipping method (it can be a fixed cost for all the shipments, a [tiered cost](/core-api-reference/shipping_weight_tiers) based on the shipment weight, or a custom cost calculated [using an external logic](/core/external-resources/external-shipping-costs)).
* Offer free shipping if the order total or subtotal is over a certain amount.
* Make the shipping method available for the previously created shipping zone, shipping category, stock location, or interval of shipment's weight.

### Payments

To be able to receive payments from your customers, you need to configure one or more payment methods. To create a payment method you must first set up:

* A [payment gateway](/core-api-reference/payment_gateways) — Commerce Layer is currently [integrated out-of-the-box](/how-tos/placing-orders/payments) with some of the most used payment providers. [Manual payments](/core-api-reference/manual_gateways) (e.g. cash on delivery, wire transfers) and the option to integrate[ any other external payment service](/core/external-resources/external-payment-gateways) are also available.

<figure><img src="/files/WDzKScouT2o1circU8I6" alt=""><figcaption></figcaption></figure>

Now you can create a [payment method](/core-api-reference/payment_methods), associate it with the [previously created market](#create-a-market) and payment gateway, and set the cost (if any) that will be charged when customers select it. Here you can also manage some specific options related to the transactions associated with the orders processed via this payment method, such as:

* [Auto-place](/core-api-reference/payment_methods#placement-options) — to automatically place orders upon receiving a successful webhook from the payment gateway.
* [Auto-capture](/how-tos/placing-orders/auto-capture) — to automatically capture payments upon authorization.
* [Delayed capture](/core-api-reference/payment_methods#capture-options) — to fulfill orders without requiring payment capture and manually capture them when ready to ship.

## Add some products

You're almost there! What you're still missing to start selling is some product variants with the related availability and prices for the previously created market:

* [SKUs](/core-api-reference/skus) — specific product variations that are being sold. You need to provide the unique SKU code and you can add a name, a description, and an image URL to be used internally. Here you can also associate the [previously created shipping category](#shipping), specify the item's weight, and indicate if the SKU refers to a digital product that doesn't involve shipments (*do not ship*) or to items with virtually unlimited stock (*do not track*).
* [Stock](/core-api-reference/stock_items) — the SKU's inventory in a specific stock location. Here you need to select the SKU, associate the [previously created stock location](#create-a-market), and specify the quantity of available units.
* [Prices](/core-api-reference/prices) — the defined cost of an SKU associated with a currency and price list. Here you need to select the SKU, associate the [previously created price list](#create-a-market), and specify the value in the selected currency. You can also set an original price to be displayed with a strikethrough and/or enable a tiered pricing policy based on [volume](/core-api-reference/price_volume_tiers) or [frequency](/core-api-reference/price_frequency_tiers).

The setup wizard will guide you through all the necessary steps to create all the resources above and your progress will be displayed in the Dashboard UI, until completion:

![](/files/8224mKIdgqpF9Us9qDWW)

## Authenticate with your API credentials

At the moment of the creation of the organization, a couple of API credentials (one of type [integration](/core/api-credentials#integration) and one of type [sales channel](/core/api-credentials#sales-channel)) are also automatically created:

<figure><img src="/files/Bvov8LAh7iLowdxdVllL" alt=""><figcaption></figcaption></figure>

You can now use them to authenticate and start using the APIs.&#x20;

{% content-ref url="/pages/-LgCGPTjMSTg9sVBpFDk" %}
[Authentication](/core/authentication)
{% endcontent-ref %}

{% content-ref url="/pages/YH8iTTmuUoiFG5ex0bNX" %}
[API credentials](/core/api-credentials)
{% endcontent-ref %}

For example, you can try to create an order using the [Orders app](https://github.com/commercelayer/dashboard-apps/tree/main/apps/orders) directly from the Dashboard and leverage our [Checkout MFE](https://github.com/commercelayer/mfe-checkout) to place it!

## Let's go deeper!

This guided setup is intended to help you put together a basic configuration for your organization but just scratches the surface of what you can build and achieve with Commerce Layer.&#x20;

Take your time to explore the rest of this guide, check the [API reference](https://docs.commercelayer.io/core-api-reference/), have a look at our recipe-like [how-tos](https://docs.commercelayer.io/how-tos/), and become a pro!

{% hint style="success" icon="chart-line-up" %}
Do you need to extract some kind of data information from your Commerce Layer's organization? Check our [Metrics API](https://docs.commercelayer.io/metrics/) and see how it can enable you to gather and aggregate useful data that you can leverage to measure the health and performance of your ecommerce business.
{% endhint %}

{% hint style="success" icon="user" %}
If you want to exercise greater control over your organizational structure and user roles and be able to manage provisioning tasks programmatically instead of manually, leverage our [Provisioning API](https://docs.commercelayer.io/provisioning/).
{% endhint %}

{% hint style="success" icon="gear-complex" %}
Would you like to benefit from a DSL that enables you to define promotional rules? If you're an enterprise customer, you can ask to test our [Rules Engine](https://docs.commercelayer.io/rules-engine/) and start setting up almost any kind of promotions to boost your sales, from the simplest to the most complex.
{% endhint %}

For everything else, [join us on Discord](https://discord.gg/commercelayer) and feel free to ask any questions to the team or get involved in the conversation with the rest of our developers' community.

If you want to dig deeper into how Commerce Layer's data model is structured, feel free to skip this initial wizard by clicking on the related text in the upper right corner and seed your organization [manually](/core/onboarding/manual-configuration), as explained in the following step-by-step guide.


# Onboarding with the CLI

Sign up for free and place your first order in a snap

As soon as you [sign up for free](https://dashboard.commercelayer.io/sign_up) and your account is successfully confirmed, you will be prompted to follow a short onboarding tutorial that will show you how to place your first order from scratch, directly from the command line.

The tutorial is split into four steps:

1. [Create an organization](#create-an-organization)
2. [Seed it with test data](#seed-the-organization-with-test-data)
3. [Place a test order](#place-a-test-order)
4. [Explore all the resources](#explore-all-the-resources)

### Create an organization

To create your first sample organization all you need to do is choose a meaningful name for it and select the region where your data will be stored.

{% hint style="warning" %}
Once the organization is created, the chosen data storage location cannot be changed anymore.
{% endhint %}

![](/files/cJvMCO6xzpkOqw4LHnUf)

{% hint style="info" %}
If — for whatever reason — you need to delete one or more of the organizations you created, please ask the organization owner to reach out to our support team and send a specific request to [support@commercelayer.io ](mailto:support@commercelayer.io)specifying the list of the organization slug you want to be deleted.
{% endhint %}

### Seed the organization with test data

You can now seed your newly created organization with some test data using the [seeder plugin](https://github.com/commercelayer/commercelayer-cli-plugin-seeder) of the CLI.

![](/files/CfMjZbwiiKAhmvvMJgkd)

### Place a test order

Once your sample organization gets populated with everything you need to get started, you can place your first order in test mode. To do that you need to generate the checkout URL using the [checkout plugin](https://github.com/commercelayer/commercelayer-cli-plugin-checkout/) of the CLI and complete the process in the browser through Commerce Layer [hosted checkout](https://github.com/commercelayer/commercelayer-react-checkout).

![](/files/8U4s7oqfqfn6og2in8Xm)

{% hint style="success" %}
Congratulations! :tada: You just placed your first order with Commerce Layer, and it took you less than 5 minutes. Cool, right?
{% endhint %}

### Explore all the resources

As the last step of your first dive into Commerce Layer we suggest you install the [resources plugin](https://github.com/commercelayer/commercelayer-cli-plugin-resources) and get more familiar with the CLI by exploring your organization's test data:

![](/files/p7MIx0nGuHwxlM5hX8jG)

{% hint style="info" %}
Please note that a live documentation option is also available on the command line: just append `--doc` to any CLI command of the resources plugin to show the command in a specific language of your choice (**cURL** and **Node** currently available, more to come).
{% endhint %}

#### Example

{% tabs %}
{% tab title="CLI command" %}
The following command fetches a collection of SKUs using the CLI, prompting you the options to select a format to show the command live documentation:

```shell
commercelayer list skus --doc
```

{% endtab %}

{% tab title="cURL" %}
This is the corresponding cURL command to fetch a collection of SKUs:

```shell
curl -g -X GET \
  'https://your-organization.commercelayer.io/api/skus' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Content-Type: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Node" %}
This is the corresponding Node command to fetch a collection of SKUs:

```javascript
import commercelayer from '@commercelayer/sdk'

const organization = 'your-organization'
const accessToken = 'your-access-token'

const cl = commercelayer({ organization, accessToken })

cl.skus.list().then(console.log)
```

{% endtab %}
{% endtabs %}

## Let's go deeper!

The onboarding tutorial just scratches the surface of what you can build and achieve with Commerce Layer. Now, you can take the time to explore the rest of this guide, check the [API reference](https://docs.commercelayer.io/core-api-reference/), have a look at our recipe-like [how-tos](https://docs.commercelayer.io/how-tos/), and become a pro!

{% hint style="success" %}
Do you need to extract some kind of data information from your Commerce Layer's organization? Check our [Metrics API](https://docs.commercelayer.io/metrics/) and see how it can enable you to gather and aggregate useful data that you can leverage to measure the health and performance of your ecommerce business.
{% endhint %}

{% hint style="success" %}
If you want to exercise greater control over your organizational structure and user roles and be able to manage provisioning tasks programmatically instead of manually, leverage our [Provisioning API](https://docs.commercelayer.io/provisioning/).
{% endhint %}

{% hint style="success" %}
Would you like to benefit from a DSL that enables you to define promotional rules? If you're an enterprise customer, you can ask to test our [Rules Engine](https://docs.commercelayer.io/rules-engine/) and start setting up almost any kind of promotions to boost your sales, from the simplest to the most complex.
{% endhint %}

For everything else, [join us on Discord](https://discord.gg/commercelayer) and feel free to ask any questions to the team or get involved in the conversation with the rest of our developers' community.

If you want to dig deeper into how Commerce Layer's data model is structured, feel free to skip this tutorial by clicking on the related text in the upper right corner, create a new organization, and [seed it manually](/core/onboarding/manual-configuration), as explained in the following step-by-step guide.


# Manual configuration

A step-by-step guide on how to set up an organization from scratch, using our CLI

If you want to get deeper and understand the Commerce Layer Core API data model in detail, you may want to try to configure your organization manually, directly interacting with our APIs by leveraging the [Commerce Layer CLI](https://github.com/commercelayer/commercelayer-cli). The manual configuration involves creating all the necessary resources, linking them based on their mutual relationships, and properly populating your environment with sample (or real) data. [This guide](#manual-seeding-reference-guide) will walk you through the process of setting up a new organization using the command line from start to finish and is a good opportunity to learn (by doing) how Commerce Layer works, in deep.

{% hint style="info" %}
Please refer to Commerce Layer Core API [data model](https://commercelayer.io/docs/data-model) documentation to get an overview of the most relevant API entities, their mutual relationships, and common usage with the help of E-R diagrams.
{% endhint %}

As an alternative, if you want to go straight to the chase, you can [follow the wizard](/core/onboarding/guided-setup) available on the Dashboard UI when you create a new organization.

## Manual seeding reference guide

1. [Create an organization](#create-an-organization)
2. [Create integration API credentials](#create-integration-api-credentials)
3. [Install the Commerce Layer CLI](#install-the-commerce-layer-cli)
4. [Log in using the API credentials](#log-in-using-the-api-credentials)
5. [Install the resources plugin](#install-the-resources-plugin)
6. [Configure your organization](#configure-your-organization)
   * [x] **Markets**
     * [Address](#address)
     * [Merchant](#merchant)
     * [Stock location](#stock-location)
     * [Inventory model](#inventory-model)
     * [Inventory stock location](#inventory-stock-location)
     * [Price list](#price-list)
     * [Market](#market)
   * [x] **Shipping**
     * [Shipping category](#shipping-category)
     * [Shipping zone](#shipping-zone)
     * [Shipping method](#shipping-method)
   * [x] **Payments**
     * [Payment gateway](#payment-gateway)
     * [Payment method](#payment-method)
   * [x] **Products**
     * [SKUs](#skus)
     * [Stock items](#stock-items)
     * [Prices](#prices)
7. [Import additional resources](#import-additional-resources)
8. [Create an order](#create-an-order)
9. [Create sales channel API credentials](#create-sales-channel-api-credentials)
10. [Generate a checkout URL](#generate-a-checkout-url)

## Create an organization

As soon as you [sign up for free](https://dashboard.commercelayer.io/sign_up) and your account is successfully confirmed, you will be prompted to create your first organization. Otherwise, if you already have an account, click on your current organization name in the left upper corner of your dashboard homepage to access your list of [organizations](https://commercelayer.io/docs/data-model/users-and-organizations) and select *+ New organization* from the dropdown to create a new one for your business. Then, on the following page, enter a name and select the region where your data will be stored, as seen in the screenshots below.

![](/files/BbwE9gkoygh1hD0rhk5f)

<figure><img src="/files/pw5MG3YFD5C2jAuildQi" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
Once the organization is created, the chosen data storage location cannot be changed anymore. If — for whatever reason — you need to delete one or more of the organizations you created, please ask the organization owner to reach out to our support team and send a specific request to [support@commercelayer.io ](mailto:support@commercelayer.io)specifying the list of the organization slug you want to be deleted.
{% endhint %}

## Create integration API credentials

Follow [these steps](/core/api-credentials#create-an-integration) to create new integration API credentials (**client ID**, **client secret**, and **base endpoint**) from the Dashboard with an **Admin** role. Remember to save them as we'll use them later to [interact with the CLI](#log-in-using-the-api-credentials).

## Install the Commerce Layer CLI

Run the command below on your terminal to install the CLI using your favorite package manager:

```shell
npm install -g @commercelayer/cli
```

```
yarn global add @commercelayer/cli
```

Installing the CLI provides access to the `commercelayer` command, which can also be accessed with the aliases `clayer` and `cl`.

{% hint style="info" %}
You can run `commercelayer help` at any point to learn about the available command options.
{% endhint %}

## Log in using the API credentials <a href="#log-in-using-the-api-credentials" id="log-in-using-the-api-credentials"></a>

Log in via the CLI using the [previously created](#create-integration-api-credentials) integration API credentials like so:

```shell
cl applications:login -o <organizationSlug> -i <clientId> -s <clientSecret> -a <applicationAlias>
```

Here’s a breakdown of each of the command options:

* The `applications:login` command lets you manage the login with the CLI using your API credentials.
* The `-o` flag allows you to pass in an organization slug as a parameter.
* `<organizationSlug>` represents the slug from your organization’s base endpoint (e.g. `sample-shop` from `https://sample-shop.commercelayer.io`).
* The `-i` flag allows you to pass in a client ID as a parameter.
* `<clientId>` represents your client ID (you can find it on the API credentials details page on the dashboard).
* The `-s` flag allows you to pass in a client secret as a parameter.
* `<clientSecret>` represents your client secret (you can find it on the API credentials details page on the dashboard).
* The `-a` flag allows you to pass in an alias that will be associated with the credentials you want to log with on your terminal (this is useful when switching between different API credentials).

## Install the resources plugin

To get started, you need to install the [resources plugin](https://github.com/commercelayer/commercelayer-cli-plugin-resources) so that you can execute CRUD operations on the API resources. To do that, use the command below:

```shell
cl plugins:install resources
```

{% hint style="info" %}
You can run the command `cl resources` to list all the available Commerce Layer API [resources](https://docs.commercelayer.io/core-api-reference/) and a link to the documentation of each one. Use `commercelayer resources --help` to see the available commands and what they do.
{% endhint %}

For this guide, we would be using:

* The `commercelayer resources:create [RESOURCE]` command to create new resources.
* The `-r, --relationship=<value>` flag which defines a relationship with another resource(s).
* The `-a, --attribute=<value>` flag which defines the attributes of a resource that will be used.

{% hint style="info" %}
Please note that a live documentation option is also available on the command line: just append `--doc` to any CLI command of the resources plugin to show the command in a specific language of your choice (**cURL** and **Node** currently available, more to come).
{% endhint %}

#### Example

{% tabs %}
{% tab title="CLI command" %}
The following command fetches a collection of SKUs using the CLI, prompting you the options to select a format to show the command live documentation:

```shell
commercelayer list skus --doc
```

{% endtab %}

{% tab title="cURL" %}
This is the corresponding cURL command to fetch a collection of SKUs:

```shell
curl -g -X GET \
  'https://your-organization.commercelayer.io/api/skus' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Content-Type: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Node" %}
This is the corresponding Node command to fetch a collection of SKUs:

```javascript
import commercelayer from '@commercelayer/sdk'

const organization = 'your-organization'
const accessToken = 'your-access-token'

const cl = commercelayer({ organization, accessToken })

cl.skus.list().then(console.log)
```

{% endtab %}
{% endtabs %}

## Configure your organization

To get your organization ready to receive orders, you need to create some resources. These resources are grouped into [Markets](#markets), [Shipping](#shipping), [Payments](#payments), and [Products](#products). The sections below describe each of these resources in sequential order, and how to create them using the [previously installed](#install-the-resources-plugin) resources plugin of the CLI. All the resources will be created using sample data, and we will add the following for each of them:

* A description of the resource with a link to the related object details in the [API reference](https://docs.commercelayer.io/core-api-reference/).
* The command for creating the resource.
* The output response of the successfully run command.
* A link to the related [data model](https://commercelayer.io/docs/data-model) where you can check the flowchart that illustrates how the specific resource relates to other API entities.

{% hint style="info" %}
When you successfully create a new resource, you can confirm this by running `cl resources:list <resource_type>` and checking if the resource is in the returned list (e.g. `cl resources:list payment_gateways` will list all the payment gateways that have been created).
{% endhint %}

### Markets

#### Address

The [address](https://docs.commercelayer.io/developers/v/api-reference/addresses/object) resource is the foundation of users and merchants in Commerce Layer. It includes the literal details of a physical address of a person. An address can be associated with other resources or orders as their shipping or billing addresses.

{% tabs %}
{% tab title="CLI command" %}
The following command creates a new address:

```shell
cl resources:create address -a \
  business="true" \
  company="Sample Shop SRL" \
  line_1="Via Roma 123" \
  city="Firenze" \
  zip_code="50123" \
  state_code="FI" \
  country_code="IT" \
  phone="+39 055 1234567890" \
  email="sample-shop@example.com"
```

{% endtab %}

{% tab title="Response" %}
On successful run, the newly created address object information is prompted:

```javascript
{
  id: 'dqJkunqnQa',
  type: 'addresses',
  business: true,
  first_name: null,
  last_name: null,
  company: 'Sample Shop SRL',
  full_name: 'Sample Shop SRL',
  line_1: 'Via Roma 123',
  line_2: null,
  city: 'Firenze',
  zip_code: '50123',
  state_code: 'FI',
  country_code: 'IT',
  phone: '+39 055 1234567890',
  full_address: 'Via Roma 123, 50123 Firenze FI (IT) +39 055 1234567890',
  name: 'Sample Shop SRL, Via Roma 123, 50123 Firenze FI (IT) +39 055 1234567890',
  email: 'sample-shop@example.com',
  notes: null,
  lat: null,
  lng: null,
  is_localized: false,
  is_geocoded: false,
  provider_name: null,
  map_url: null,
  static_map_url: null,
  billing_info: null,
  created_at: '2022-03-17T14:27:26.526Z',
  updated_at: '2022-03-17T14:27:26.526Z',
  reference: null,
  reference_origin: null,
  metadata: {}
}
```

{% endtab %}
{% endtabs %}

#### Merchant

A [merchant](https://docs.commercelayer.io/developers/v/api-reference/merchants/object) is a fiscal representative that is selling in a specific market. Tax calculators use the merchant's address to determine the tax rate for an order. The merchant needs to be associated with a billing address. To do that we will use the ID from the [previously created](#address) address resource.

{% tabs %}
{% tab title="CLI command" %}
The following command creates a new merchant and associates it with a billing address:

```shell
cl resources:create merchants -a \
  name="Sample Shop Manager" -r \
  address="dqJkunqnQa"
```

{% endtab %}

{% tab title="Response" %}
On successful run, the newly created merchant object information is prompted:

```javascript
{
  id: 'qnzZLHrgmn',
  type: 'merchants',
  name: 'Sample Shop Manager',
  created_at: '2022-03-17T14:28:27.008Z',
  updated_at: '2022-03-17T14:28:27.008Z',
  reference: null,
  reference_origin: null,
  metadata: {},
  address: {
    id: 'dqJkunqnQa',
    type: 'addresses',
    business: true,
    first_name: null,
    last_name: null,
    company: 'Sample Shop SRL',
    full_name: 'Sample Shop SRL',
    line_1: 'Via Roma 123',
    line_2: null,
    city: 'Firenze',
    zip_code: '50123',
    state_code: 'FI',
    country_code: 'IT',
    phone: '+39 055 1234567890',
    full_address: 'Via Roma 123, 50123 Firenze FI (IT) +39 055 1234567890',
    name: 'Sample Shop SRL, Via Roma 123, 50123 Firenze FI (IT) +39 055 1234567890',
    email: 'sample-shop@example.com',
    notes: null,
    lat: null,
    lng: null,
    is_localized: false,
    is_geocoded: false,
    provider_name: null,
    map_url: null,
    static_map_url: null,
    billing_info: null,
    created_at: '2022-03-17T14:27:26.526Z',
    updated_at: '2022-03-17T14:27:26.526Z',
    reference: null,
    reference_origin: null,
    metadata: {}
  }
}
```

{% endtab %}
{% endtabs %}

{% embed url="<https://commercelayer.io/docs/data-model/merchants-and-customers>" %}

#### Stock location

[Stock locations](https://docs.commercelayer.io/developers/v/api-reference/stock_locations/object) contain the inventory of the SKUs (stock items) that are to be sold. A new stock location needs to be associated with an address. If the address is different from the merchant's one, then you should create a new address following [the same method above](#address) and use the new address ID here. To keep it simple, we’ll use the merchant’s address.

{% tabs %}
{% tab title="CLI command" %}
The following command creates a new stock location and associates it with an address:

```shell
cl resources:create stock_locations -a \
  name="Europe Warehouse" -r \
  address="dqJkunqnQa"
```

{% endtab %}

{% tab title="Response" %}
On successful run, the newly created stock location object information is prompted:

```javascript
{
  id: 'okdYzuXRDM',
  type: 'stock_locations',
  number: 8207,
  name: 'Europe Warehouse',
  label_format: 'PDF',
  suppress_etd: null,
  created_at: '2022-03-17T14:29:43.763Z',
  updated_at: '2022-03-17T14:29:43.763Z',
  reference: null,
  reference_origin: null,
  metadata: {},
  address: {
    id: 'dqJkunqnQa',
    type: 'addresses',
    business: true,
    first_name: null,
    last_name: null,
    company: 'Sample Shop SRL',
    full_name: 'Sample Shop SRL',
    line_1: 'Via Roma 123',
    line_2: null,
    city: 'Firenze',
    zip_code: '50123',
    state_code: 'FI',
    country_code: 'IT',
    phone: '+39 055 1234567890',
    full_address: 'Via Roma 123, 50123 Firenze FI (IT) +39 055 1234567890',
    name: 'Sample Shop SRL, Via Roma 123, 50123 Firenze FI (IT) +39 055 1234567890',
    email: 'sample-shop@example.com',
    notes: null,
    lat: null,
    lng: null,
    is_localized: false,
    is_geocoded: false,
    provider_name: null,
    map_url: null,
    static_map_url: null,
    billing_info: null,
    created_at: '2022-03-17T14:27:26.526Z',
    updated_at: '2022-03-17T14:27:26.526Z',
    reference: null,
    reference_origin: null,
    metadata: {}
  }
}
```

{% endtab %}
{% endtabs %}

{% embed url="<https://commercelayer.io/docs/data-model/stock-locations>" %}

#### Inventory model

An [inventory model](https://docs.commercelayer.io/developers/v/api-reference/inventory_models/object) defines a list of stock locations ordered by priority. The priority determines how the availability of SKUs gets calculated within a market. If an order contains line items from two or more stock locations, the order can be split into two or more shipments, according to the selected [inventory strategy](https://docs.commercelayer.io/developers/v/how-tos/inventory-model-strategies).

{% tabs %}
{% tab title="CLI command" %}
The following command creates a new inventory model:

```shell
cl resources:create inventory_models -a name="EUR Inventory"
```

{% endtab %}

{% tab title="Response" %}
On successful run, the newly created inventory model object information is prompted:

```javascript
{
  id: 'kZXEvSYlra',
  type: 'inventory_models',
  name: 'EUR Inventory',
  strategy: 'split_shipments',
  stock_locations_cutoff: 2,
  created_at: '2022-03-17T14:32:17.869Z',
  updated_at: '2022-03-17T14:32:17.869Z',
  reference: null,
  reference_origin: null,
  metadata: {}
}
```

{% endtab %}
{% endtabs %}

{% embed url="<https://commercelayer.io/docs/data-model/inventory-models>" %}

#### Inventory stock location

[Inventory stock locations](https://docs.commercelayer.io/developers/v/api-reference/inventory_stock_locations/object) build a hierarchy of stock locations within an inventory model. In cases where an SKU is available in more stock locations, it gets shipped from the one with the highest priority. You can decide to put the associated shipments on hold if fulfilled from a specific stock location (false by default). This is useful to manage use cases like back-orders, pre-orders, or personalized orders that need to be customized before being fulfilled. To create a new inventory stock location, you need to associate it with a stock location and an inventory model. We will use the ones we created earlier.

{% tabs %}
{% tab title="CLI command" %}
The following command creates a new inventory stock location and associates it with a stock location and an inventory model:

```shell
cl resources:create inventory_stock_locations -r \
  inventory_model="kZXEvSYlra" \
  stock_location="okdYzuXRDM" -a \
  priority="4"
```

{% endtab %}

{% tab title="Response" %}
On successful run, the newly created inventory stock location object information is prompted:

```javascript
{
  id: 'aWDOVSOBzj',
  type: 'inventory_stock_locations',
  priority: 4,
  on_hold: false,
  created_at: '2022-03-17T14:33:20.771Z',
  updated_at: '2022-03-17T14:33:20.771Z',
  reference: null,
  reference_origin: null,
  metadata: {},
  stock_location: {
    id: 'okdYzuXRDM',
    type: 'stock_locations',
    number: 8207,
    name: 'Europe Warehouse',
    label_format: 'PDF',
    suppress_etd: null,
    created_at: '2022-03-17T14:29:43.763Z',
    updated_at: '2022-03-17T14:29:43.763Z',
    reference: null,
    reference_origin: null,
    metadata: {}
  },
  inventory_model: {
    id: 'kZXEvSYlra',
    type: 'inventory_models',
    name: 'EUR Inventory',
    strategy: 'split_shipments',
    stock_locations_cutoff: 2,
    created_at: '2022-03-17T14:32:17.869Z',
    updated_at: '2022-03-17T14:32:17.869Z',
    reference: null,
    reference_origin: null,
    metadata: {}
  }
}
```

{% endtab %}
{% endtabs %}

#### Price list

[Price lists](https://docs.commercelayer.io/developers/v/api-reference/price_lists/object) determine the SKU prices and their currency within a market. When you create a price list you have to specify the related currency and you can decide whether the associated prices include taxes or not (by default taxes are included).

{% tabs %}
{% tab title="CLI command" %}
The following command creates a new price list associated with the European currency, with tax included (default):

```shell
cl resources:create price_lists -a \
  name="Euros Price List" \
  currency_code="EUR"
```

{% endtab %}

{% tab title="Response" %}
On successful run, the newly created price list object information is prompted. You can see that the taxes have been included by default:

```javascript
{
  id: 'dlwQyCXnqB',
  type: 'price_lists',
  name: 'Euros Price List',
  currency_code: 'EUR',
  tax_included: true,
  created_at: '2022-03-17T14:37:44.720Z',
  updated_at: '2022-03-17T14:37:44.720Z',
  reference: null,
  reference_origin: null,
  metadata: {}
}
```

{% endtab %}
{% endtabs %}

{% embed url="<https://commercelayer.io/docs/data-model/price-lists-and-currencies>" %}

#### Market

A [market](https://docs.commercelayer.io/developers/v/api-reference/markets/object) is an aggregation of business rules, often determined by a geographical region where merchants can sell items and customers can purchase. An organization may have one or more markets associated with a merchant, inventory model, SKUs, price lists, stock items, customer groups, and more. When you create a new market you need at least to associate it with a merchant, an inventory model, and a price list. We will use the ones we created earlier.

{% tabs %}
{% tab title="CLI command" %}
The following command creates a new market and associate it list associates it with a merchant, an inventory model, and a price list:

```shell
cl resources:create markets -r \
  merchant="qnzZLHrgmn" \
  inventory_model="kZXEvSYlra" \
  price_list="dlwQyCXnqB" -a \
  name="Europe"
```

{% endtab %}

{% tab title="Response" %}
On successful run, the newly created market object information is prompted:

```javascript
{
  id: 'BjydJhAPko',
  type: 'markets',
  number: 9656,
  name: 'Europe',
  facebook_pixel_id: null,
  checkout_url: null,
  external_prices_url: null,
  private: false,
  created_at: '2022-03-17T14:39:47.525Z',
  updated_at: '2022-03-17T14:39:47.525Z',
  reference: null,
  reference_origin: null,
  metadata: {},
  merchant: {
    id: 'qnzZLHrgmn',
    type: 'merchants',
    name: 'Sample Shop Manager',
    created_at: '2022-03-17T14:28:27.008Z',
    updated_at: '2022-03-17T14:28:27.008Z',
    reference: null,
    reference_origin: null,
    metadata: {}
  },
  price_list: {
    id: 'dlwQyCXnqB',
    type: 'price_lists',
    name: 'Euros Price List',
    currency_code: 'EUR',
    tax_included: true,
    created_at: '2022-03-17T14:37:44.720Z',
    updated_at: '2022-03-17T14:37:44.720Z',
    reference: null,
    reference_origin: null,
    metadata: {}
  },
  inventory_model: {
    id: 'kZXEvSYlra',
    type: 'inventory_models',
    name: 'EUR Inventory',
    strategy: 'split_shipments',
    stock_locations_cutoff: 2,
    created_at: '2022-03-17T14:32:17.869Z',
    updated_at: '2022-03-17T14:32:17.869Z',
    reference: null,
    reference_origin: null,
    metadata: {}
  }
}
```

{% endtab %}
{% endtabs %}

{% embed url="<https://commercelayer.io/docs/data-model/markets-and-business-models>" %}

### Shipping

#### Shipping category

[Shipping categories](https://docs.commercelayer.io/developers/v/api-reference/shipping_categories/object) determine which shipping methods are available for the associated SKUs. With this, an order will be split into multiple shipments if it contains line items belonging to more than one shipping category.

{% tabs %}
{% tab title="CLI command" %}
The following command creates a new shipping category:

```shell
cl resources:create shipping_categories -a name="Demo Shipping Category"
```

{% endtab %}

{% tab title="Response" %}
On successful run, the newly created shipping category object information is prompted:

```javascript
{
  id: 'MWjgYFbYVK',
  type: 'shipping_categories',
  name: 'Demo Shipping Category',
  created_at: '2022-03-17T14:41:06.380Z',
  updated_at: '2022-03-17T14:41:06.380Z',
  reference: null,
  reference_origin: null,
  metadata: {}
}
```

{% endtab %}
{% endtabs %}

{% embed url="<https://commercelayer.io/docs/data-model/shipments-and-shipping-categories>" %}

#### Shipping zone

[Shipping zones](https://docs.commercelayer.io/developers/v/api-reference/shipping_zones/object) determine the available shipping method(s) for a given shipping address. The match is evaluated against a set of regular expressions on the address (country, state, or zip code) of a customer. Now let’s create a new shipping zone to match Italy (IT), Spain (ES), Germany (DE), France (FR), and the United Kingdom (UK).

{% tabs %}
{% tab title="CLI command" %}
The following command creates a new shipping zone to match Italy (IT), Spain (ES), Germany (DE), France (FR), and the United Kingdom (UK):

```shell
cl resources:create shipping_zones -a \
  name="European Countries" \
  country_code_regex="IT|ES|DE|FR|UK"
```

{% endtab %}

{% tab title="Response" %}
On successful run, the newly created shipping zone object information is prompted:

```javascript
{
  id: 'kKwxmtNVYv',
  type: 'shipping_zones',
  name: 'European Countries',
  country_code_regex: 'IT|ES|DE|FR|UK',
  not_country_code_regex: null,
  state_code_regex: null,
  not_state_code_regex: null,
  zip_code_regex: null,
  not_zip_code_regex: null,
  created_at: '2022-03-17T14:41:39.794Z',
  updated_at: '2022-03-17T14:41:39.794Z',
  reference: null,
  reference_origin: null,
  metadata: {}
}
```

{% endtab %}
{% endtabs %}

{% embed url="<https://commercelayer.io/docs/data-model/shipping-zones-and-methods>" %}

#### Shipping method

[Shipping methods](https://docs.commercelayer.io/developers/v/api-reference/shipping_methods/object) are used to provide customers with delivery options. Each shipping method can have a price and can be free if the order total is over a certain amount or based on some specific promotion rules. When you create a new shipping method you need to specify its cost (amount) and the currency code. If you associate the shipping method with a market, the currency will be inherited from the market's price list. You need also to associate it with a shipping zone and a shipping category. We will use the previously created ones.

{% tabs %}
{% tab title="CLI command" %}
The following command creates a new shipping method and associates it with a market, a shipping zone, and a shipping category.

```shell
cl resources:create shipping_methods -r \
  market="BjydJhAPko" \
  shipping_zone="kKwxmtNVYv" \
  shipping_category="MWjgYFbYVK" -a \
  name="Express Delivery" \
  price_amount_cents="960" \
  free_over_amount_cents="8900"
```

{% endtab %}

{% tab title="Response" %}
On successful run, the newly created shipping method object information is prompted. You can see that the currency code (EUR) has been inherited by the market's price list:

```javascript
{
  id: 'bVlBrFyGKO',
  type: 'shipping_methods',
  name: 'Express Delivery',
  currency_code: 'EUR',
  disabled_at: null,
  price_amount_cents: 960,
  price_amount_float: 9.6,
  formatted_price_amount: '€9,60',
  free_over_amount_cents: 8900,
  free_over_amount_float: 89,
  formatted_free_over_amount: '€89,00',
  price_amount_for_shipment_cents: 960,
  price_amount_for_shipment_float: 9.6,
  formatted_price_amount_for_shipment: '€9,60',
  created_at: '2022-03-17T14:44:22.650Z',
  updated_at: '2022-03-17T14:44:22.650Z',
  reference: null,
  reference_origin: null,
  metadata: {},
  market: {
    id: 'BjydJhAPko',
    type: 'markets',
    number: 9656,
    name: 'Europe',
    facebook_pixel_id: null,
    checkout_url: null,
    external_prices_url: null,
    private: false,
    created_at: '2022-03-17T14:39:47.525Z',
    updated_at: '2022-03-17T14:39:47.525Z',
    reference: null,
    reference_origin: null,
    metadata: {}
  },
  shipping_zone: {
    id: 'kKwxmtNVYv',
    type: 'shipping_zones',
    name: 'European Countries',
    country_code_regex: 'IT|ES|DE|FR|UK',
    not_country_code_regex: null,
    state_code_regex: null,
    not_state_code_regex: null,
    zip_code_regex: null,
    not_zip_code_regex: null,
    created_at: '2022-03-17T14:41:39.794Z',
    updated_at: '2022-03-17T14:41:39.794Z',
    reference: null,
    reference_origin: null,
    metadata: {}
  },
  shipping_category: {
    id: 'MWjgYFbYVK',
    type: 'shipping_categories',
    name: 'Demo Shipping Category',
    created_at: '2022-03-17T14:41:06.380Z',
    updated_at: '2022-03-17T14:41:06.380Z',
    reference: null,
    reference_origin: null,
    metadata: {}
  }
}
```

{% endtab %}
{% endtabs %}

{% embed url="<https://commercelayer.io/docs/data-model/shipping-zones-and-methods>" %}

### Payments

#### Payment gateway

[Payment gateways](https://docs.commercelayer.io/developers/v/api-reference/payment_gateways/object) allow users to process payments through Commerce Layer's API. By default, we currently support [Adyen](https://docs.commercelayer.io/developers/v/api-reference/adyen_gateways/object), [Braintree](https://docs.commercelayer.io/developers/v/api-reference/braintree_gateways/object), [Checkout.com](https://docs.commercelayer.io/developers/v/api-reference/checkout_com_gateways/object), [Klarna](https://docs.commercelayer.io/developers/v/api-reference/klarna_gateways/object), [PayPal](https://docs.commercelayer.io/developers/v/api-reference/paypal_gateways), and [Stripe](https://docs.commercelayer.io/developers/v/api-reference/stripe_gateways/object). [Manual gateways](https://docs.commercelayer.io/developers/v/api-reference/manual_gateways/object) are also available (useful to process payments through wire transfer, cash, and other kinds of manual payment options). On top of that, [external gateways](https://docs.commercelayer.io/developers/v/api-reference/external_gateways/object) let you integrate any payment service that is not available out-of-the-box (even your custom one). You can check the API references of each of them to understand the attributes/relationships required for their creation. For the purpose of this guide, we will create a manual gateway

{% tabs %}
{% tab title="CLI command" %}
The following command creates a new manual payment gateway:

```shell
cl resources:create manual_gateways -a name="Manual Gateway"
```

{% endtab %}

{% tab title="Response" %}
On successful run, the newly created manual payment gateway object information is prompted:

```javascript
{
  id: 'ExJwlspqmv',
  type: 'manual_gateways',
  name: 'Manual Gateway',
  created_at: '2022-03-17T14:45:27.063Z',
  updated_at: '2022-03-17T14:45:27.063Z',
  reference: null,
  reference_origin: null,
  metadata: {},
  require_capture: null
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
You can use the command `cl resources:list payment_gateways` to list all the payment gateway(s) created or `cl resources:list <gateway_type>_gateways` to list only the specified ’s payment gateways created.
{% endhint %}

{% embed url="<https://commercelayer.io/docs/data-model/payment-gateways>" %}

#### Payment method

[Payment methods](https://docs.commercelayer.io/developers/v/api-reference/payment_methods/object) represent the type of payment sources (e.g. credit card, PayPal, or Apple Pay) offered in a market. They can have a price and must be present before placing an order. By default, we currently support the following payment source types: [Adyen payment](https://docs.commercelayer.io/developers/v/api-reference/adyen_payments/object), [Braintree payment](https://docs.commercelayer.io/developers/v/api-reference/braintree_payments/object), [Checkout.com payment](https://docs.commercelayer.io/developers/v/api-reference/checkout_com_payments/object), credit card, [PayPal payment](https://docs.commercelayer.io/developers/v/api-reference/paypal_payments/object), [Stripe payment](https://docs.commercelayer.io/developers/v/api-reference/stripe_payments/object), [external payment](https://docs.commercelayer.io/developers/v/api-reference/external_payments/object), or [wire transfer](https://docs.commercelayer.io/developers/v/api-reference/wire_transfers/object) — based on the payment gateway to be associated with. The manual payment gateway only accepts the wire transfer payment source type and that's the one we will use to create the payment method, associated with the previously created payment gateway.

{% tabs %}
{% tab title="CLI command" %}
The following command creates a new payment method and associates it with a manual payment gateway and a wire transfer payment source:

```shell
cl resources:create payment_methods -r \
  market="BjydJhAPko" \
  payment_gateway="ExJwlspqmv" -a \
  payment_source_type="WireTransfer"
```

{% endtab %}

{% tab title="Response" %}
On successful run, the newly created payment method object information is prompted:

```javascript
{
  id: 'lMAeGsQQWM',
  type: 'payment_methods',
  payment_source_type: 'wire_transfers',
  name: 'Wire Transfer',
  currency_code: 'EUR',
  moto: false,
  disabled_at: null,
  price_amount_cents: 0,
  price_amount_float: 0,
  formatted_price_amount: '€0,00',
  created_at: '2022-03-17T14:50:17.021Z',
  updated_at: '2022-03-17T14:50:17.021Z',
  reference: null,
  reference_origin: null,
  metadata: {},
  market: {
    id: 'BjydJhAPko',
    type: 'markets',
    number: 9656,
    name: 'Europe',
    facebook_pixel_id: null,
    checkout_url: null,
    external_prices_url: null,
    private: false,
    created_at: '2022-03-17T14:39:47.525Z',
    updated_at: '2022-03-17T14:39:47.525Z',
    reference: null,
    reference_origin: null,
    metadata: {}
  },
  payment_gateway: {
    id: 'ExJwlspqmv',
    type: 'payment_gateways',
    name: 'Manual Gateway',
    created_at: '2022-03-17T14:45:27.063Z',
    updated_at: '2022-03-17T14:45:27.063Z',
    reference: null,
    reference_origin: null,
    metadata: {}
  }
}
```

{% endtab %}
{% endtabs %}

{% embed url="<https://commercelayer.io/docs/data-model/payment-methods>" %}

### Products

#### SKUs

[SKUs](https://docs.commercelayer.io/developers/v/api-reference/skus/object) describe specific product variations that are being sold. To create an SKU you need to associate it with a shipping category that determines the available shipping options for that SKU. We will use the [previously created](#shipping-category) one. You can add any additional optional attribute that fits your needs.

{% tabs %}
{% tab title="CLI command" %}
The following command created a new SKU and associates it with a shipping category:

```shell
cl resources:create skus -r \
  shipping_category="MWjgYFbYVK" -a \
  code="SKUCODE0001XLXX" \
  name="Grey Aeron Ergonomic Office Chair" \
  description="Aeron office chair is a revolutionized office seating with its defining design qualities and its patented PostureFit SL back support..." \
  image_url="https://images.hermanmiller.group/m/7b7b8463a1433d26/W-REK_18179_20160811174200565.png" \
  reference="SKUCODE0001" \
  do_not_ship="false" \
  do_not_track="false" \
  weight="500" \
  unit_of_weight="gr"
```

{% endtab %}

{% tab title="Response" %}
On successful run, the newly created SKU object information is prompted:

```javascript
{
  id: 'BorzSOKrYq',
  type: 'skus',
  code: 'SKUCODE0001XLXX',
  name: 'Grey Aeron Ergonomic Office Chair',
  description: 'Aeron office chair is a revolutionized office seating with its defining design qualities and its patented PostureFit SL back support...',
  image_url: 'https://images.hermanmiller.group/m/7b7b8463a1433d26/W-REK_18179_20160811174200565.png',
  pieces_per_pack: null,
  weight: 500,
  unit_of_weight: 'gr',
  hs_tariff_number: null,
  do_not_ship: false,
  do_not_track: false,
  created_at: '2022-03-17T14:54:33.123Z',
  updated_at: '2022-03-17T14:54:33.123Z',
  reference: 'SKUCODE0001',
  reference_origin: null,
  metadata: {},
  shipping_category: {
    id: 'MWjgYFbYVK',
    type: 'shipping_categories',
    name: 'Demo Shipping Category',
    created_at: '2022-03-17T14:41:06.380Z',
    updated_at: '2022-03-17T14:41:06.380Z',
    reference: null,
    reference_origin: null,
    metadata: {}
  }
}
```

{% endtab %}
{% endtabs %}

{% embed url="<https://commercelayer.io/docs/data-model/skus>" %}

#### Stock items

A [stock item](https://docs.commercelayer.io/developers/v/api-reference/stock_items/object) keeps the available inventory of an SKU in a given stock location. When you create a stock item, you must specify its quantity, and the associated SKU must be available in one of the market's stock locations.

{% tabs %}
{% tab title="CLI command" %}
The following command creates a new stock item for a given SKU and associates it with a stock location:

```shell
cl resources:create stock_items -a \
  sku_code="SKUCODE0001XLXX" \
  quantity="100" -r \
  stock_location="okdYzuXRDM"
```

{% endtab %}

{% tab title="Response" %}
On successful run, the newly created stock item object information is prompted:

```javascript
{
  id: 'YqAwfbkwlk',
  type: 'stock_items',
  sku_code: 'SKUCODE0001XLXX',
  quantity: 100,
  created_at: '2022-03-17T14:56:11.749Z',
  updated_at: '2022-03-17T14:56:11.749Z',
  reference: null,
  reference_origin: null,
  metadata: {},
  stock_location: {
    id: 'okdYzuXRDM',
    type: 'stock_locations',
    number: 8207,
    name: 'Europe Warehouse',
    label_format: 'PDF',
    suppress_etd: null,
    created_at: '2022-03-17T14:29:43.763Z',
    updated_at: '2022-03-17T14:29:43.763Z',
    reference: null,
    reference_origin: null,
    metadata: {}
  }
}
```

{% endtab %}
{% endtabs %}

{% embed url="<https://commercelayer.io/docs/data-model/stock-items>" %}

#### Prices

[Prices](https://docs.commercelayer.io/developers/v/api-reference/prices/object) are the defined cost price of an SKU associated with a currency and price list. When a customer purchases an SKU, it gets the price associated with the order's price list for that market.\
When you create a price, you must specify the amount and the compare-at amount. The currency is defined by the associated price list.

{% tabs %}
{% tab title="CLI command" %}
The following command creates a price for a given SKU and associates it with a price list:

```shell
cl resources:create prices -a \
  sku_code="SKUCODE0001LXXX" \
  amount_cents="4990" \
  compare_at_amount_cents="4500" -r \
  sku="BorzSOKrYq" \
  price_list="dlwQyCXnqB"
```

{% endtab %}

{% tab title="Response" %}
On successful run, the newly created price object information is prompted:

```javascript
{
  id: 'anOlUkBkyE',
  type: 'prices',
  currency_code: 'EUR',
  sku_code: 'SKUCODE0001XLXX',
  amount_cents: 4990,
  amount_float: 49.9,
  formatted_amount: '€49,90',
  compare_at_amount_cents: 4990,
  compare_at_amount_float: 49.9,
  formatted_compare_at_amount: '€49,90',
  created_at: '2022-03-17T14:57:14.467Z',
  updated_at: '2022-03-17T14:57:14.467Z',
  reference: null,
  reference_origin: null,
  metadata: {},
  price_list: {
    id: 'dlwQyCXnqB',
    type: 'price_lists',
    name: 'Euros Price List',
    currency_code: 'EUR',
    tax_included: true,
    created_at: '2022-03-17T14:37:44.720Z',
    updated_at: '2022-03-17T14:37:44.720Z',
    reference: null,
    reference_origin: null,
    metadata: {}
  },
  sku: {
    id: 'BorzSOKrYq',
    type: 'skus',
    code: 'SKUCODE0001XLXX',
    name: 'Grey Aeron Ergonomic Office Chair',
    description: 'Aeron office chair is a revolutionized office seating with its defining design qualities and its patented PostureFit SL back support...',
    image_url: 'https://images.hermanmiller.group/m/7b7b8463a1433d26/W-REK_18179_20160811174200565.png',
    pieces_per_pack: null,
    weight: 500,
    unit_of_weight: 'gr',
    hs_tariff_number: null,
    do_not_ship: false,
    do_not_track: false,
    created_at: '2022-03-17T14:54:33.123Z',
    updated_at: '2022-03-17T14:54:33.123Z',
    reference: 'SKUCODE0001',
    reference_origin: null,
    metadata: {}
  }
}
```

{% endtab %}
{% endtabs %}

{% embed url="<https://commercelayer.io/docs/data-model/price-lists-and-currencies>" %}

## Import additional resources

Commerce Layer lets you import multiple resources (e.g. orders, coupons, SKUs, prices, stock items, customers, and more) in batches directly with our [imports API](https://docs.commercelayer.io/developers/v/api-reference/imports/object). All you have to do is create a new import resource, specify the resource type you want to import, and populate the inputs attribute with a JSON list of items. Each element of the inputs array contains the resource attributes and relationships. You can learn more about importing resources in our documentation.

{% content-ref url="/pages/-M9TjTH488kSdt3AliPK" %}
[Importing resources](/core/importing-resources)
{% endcontent-ref %}

To do that using the CLI, first you need to install the [imports plugin](https://github.com/commercelayer/commercelayer-cli-plugin-imports):

```shell
cl plugins:install imports
```

Then create a JSON file named `skus.json` with an array containing the list of additional SKUs you want to import:

```json
[
  {
    "code": "BEACHBAGFFFFFF000000XXXX",
    "name": "White Beach Bag with Black Logo",
    "description": "Meet your companion for a sunny summer day — our beach bag! It's large, comfy, and you can match it with our towel to create the perfect beach combo.",
    "image_url": "https://data.commercelayer.app/seed/images/skus/BEACHBAGFFFFFF000000XXXX_FLAT.png",
    "reference": "BEACHBAGFFFFFF000000",
    "shipping_category_id": "MWjgYFbYVK"
  },
  {
    "code": "BEANIEXX000000FFFFFFXXXX",
    "name": "Black Beanie with White Logo",
    "description": "Soft double-layered customizable beanie. 95% polyester, 5% spandex. Regular fit. Accurately printed, cut, and hand-sewn.",
    "image_url": "https://data.commercelayer.app/seed/images/skus/BEANIEXX000000FFFFFFXXXX_FLAT.png",
    "reference": "BEANIEXX000000FFFFFF",
    "shipping_category_id": "MWjgYFbYVK"
  }
]
```

Also, create a JSON file named `stock_items.json` with an array containing the list of the related stock items:

```json
[
  {
    "sku_code": "BEACHBAGFFFFFF000000XXXX",
    "quantity": 200
  },
  {
    "sku_code": "BEANIEXX000000FFFFFFXXXX",
    "quantity": 95
  }
]
```

Lastly, create a JSON file named `prices.json` with an array containing the list of the related prices:

```json
[
  {
    "sku_code": "BEACHBAGFFFFFF000000XXXX",
    "amount_cents": 3990,
    "compare_at_amount_cents": 5000
  },
  {
    "sku_code": "BEANIEXX000000FFFFFFXXXX",
    "amount_cents": 3490,
    "compare_at_amount_cents": 4700
  }
]
```

Now you can import the two SKUs with their prices and stock items as seen in the snippets below:

{% tabs %}
{% tab title="CLI command" %}
The following command imports the SKUs specified in a file:

```shell
cl imports:create -t skus -i <input-file-path>
```

{% endtab %}

{% tab title="Response" %}
On successful run, a brief report of the import process is prompted:

```shell
|     ID     |Items|   %  |    Status   | TBP↓ | Prc. | Wrn. | Err. |
---------------------------------------------------------------------
| mLGpILVVvg | 1-2 | 100% | completed   |    0 |    2 |    0 |

Import of 2 skus completed.
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="CLI command" %}
The following command imports the stock items specified in a file and associates them with a stock location:

```shell
cl imports:create -t stock_items -p <stock_location-id> -i <input-file-path>
```

{% endtab %}

{% tab title="Response" %}
On successful run, a brief report of the import process is prompted:

```shell
|     ID     |Items|   %  |    Status   | TBP↓ | Prc. | Wrn. | Err. |
---------------------------------------------------------------------
| qKnWIaQQlP | 1-2 | 100% | completed   |    0 |    2 |    0 |

Import of 2 stock items completed.
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="CLI command" %}
The following command imports the prices specified in a file and associates them with a price list:

```shell
cl imports:create -t prices -p <price-list-id> -i <input-file-path>
```

{% endtab %}

{% tab title="Response" %}
On successful run, a brief report of the import process is prompted:

```shell
|     ID     |Items|   %  |    Status   | TBP↓ | Prc. | Wrn. | Err. |
---------------------------------------------------------------------
| AJNpIpDDGy | 1-2 | 100% | completed   |    0 |    2 |    0 |

Import of 2 prices completed.
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
If you run into any error, you can run `cl imports:details <ID> -l` to view the error log for that import process using the process ID.
{% endhint %}

## Create an order

An [order](https://docs.commercelayer.io/core/v/api-reference/orders) consists of a customer, some line items (SKUs, shipping method, payment method, taxes, etc.), a billing address, a shipping address, discount(s) calculated from active promotions, redeemed gift card(s), a payment method, and a payment source type. The sections below will walk you through the process of creating an order by associating it with the required resources, step by step.

{% embed url="<https://commercelayer.io/docs/data-model/anatomy-of-an-order>" %}

{% hint style="success" %}
Remember that to place and checkout an order you can also leverage our hosted checkout application (automatically enabled for every Commerce Layer account) — if you want to learn more about how to generate a checkout URL using our CLI, feel free to skip the manual steps below and jump directly [here](#checkout-one-or-more-skus).
{% endhint %}

#### Search for the ID of the SKU you intend to purchase

You can find the ID of the SKU you want to purchase in the dashboard. Alternatively, you can use the CLI:

{% tabs %}
{% tab title="CLI command" %}
The following command will search for all SKUs and filter out the results:

```shell
cl resources:get skus -w name_i_cont_all=t-shirt,black -w name_not_i_cont_all=women,white
```

{% endtab %}

{% tab title="Response" %}
On successful run, an array of SKUs that match the search query is prompted:

```javascript
[
  {
    id: 'WKjRSOlEOP',
    type: 'skus',
    code: 'TSHIRTMSB0B0B2000000LXXX',
    name: 'Men's Gray T-Shirt with Black Logo (L)',
    description: "This is THE classic t-shirt. Its fine jersey cotton construction makes it extremely soft and comfortable to wear, so it's a good choice for a day-to-day outfit — it's durable and can withstand several washings while retaining its shape and color.",
    image_url: 'https://data.commercelayer.app/seed/images/skus/TSHIRTMSB0B0B2000000LXXX_FLAT.png',
    pieces_per_pack: null,
    weight: null,
    unit_of_weight: null,
    hs_tariff_number: null,
    do_not_ship: false,
    do_not_track: false,
    created_at: '2022-02-22T04:13:02.232Z',
    updated_at: '2022-02-22T04:13:02.232Z',
    reference: 'sku_219',
    reference_origin: 'CLI',
    metadata: {}
  },
  {
    id: 'WJoqSjvNjw',
    type: 'skus',
    code: 'TSHIRTMSB0B0B2000000MXXX',
    name: 'Men's Gray T-Shirt with Black Logo (M)',
    description: "This is THE classic t-shirt. Its fine jersey cotton construction makes it extremely soft and comfortable to wear, so it's a good choice for a day-to-day outfit — it's durable and can withstand several washings while retaining its shape and color.",
    image_url: 'https://data.commercelayer.app/seed/images/skus/TSHIRTMSB0B0B2000000MXXX_FLAT.png',
    pieces_per_pack: null,
    weight: null,
    unit_of_weight: null,
    hs_tariff_number: null,
    do_not_ship: false,
    do_not_track: false,
    created_at: '2022-02-22T04:13:05.219Z',
    updated_at: '2022-02-22T04:13:05.219Z',
    reference: 'sku_220',
    reference_origin: 'CLI',
    metadata: {}
  },
  {
    id: 'WaDeSyLbyg',
    type: 'skus',
    code: 'TSHIRTMSB0B0B2000000SXXX',
    name: 'Men's Gray T-Shirt with Black Logo (S)',
    description: "This is THE classic t-shirt. Its fine jersey cotton construction makes it extremely soft and comfortable to wear, so it's a good choice for a day-to-day outfit — it's durable and can withstand several washings while retaining its shape and color.",
    image_url: 'https://data.commercelayer.app/seed/images/skus/TSHIRTMSB0B0B2000000SXXX_FLAT.png',
    pieces_per_pack: null,
    weight: null,
    unit_of_weight: null,
    hs_tariff_number: null,
    do_not_ship: false,
    do_not_track: false,
    created_at: '2022-02-22T04:13:08.246Z',
    updated_at: '2022-02-22T04:13:08.246Z',
    reference: 'sku_221',
    reference_origin: 'CLI',
    metadata: {}
  },
  {
  ...
  }
]
```

{% endtab %}
{% endtabs %}

#### Search for the ID of the market you intend to purchase from

You can find the ID of the market you want to purchase from in the dashboard. Alternatively, you can use the CLI (feel free to filter out the results as shown in the [previous section](#search-for-the-id-of-the-sku-you-intend-to-purchase) if the list of your markets is too long):

{% tabs %}
{% tab title="CLI command" %}
The following command will search for all existing markets:

```shell
cl resources:get markets
```

{% endtab %}

{% tab title="Response" %}
On successful run, an array of existing markets is prompted:

```javascript
[
  {
    id: 'QlNQVhWxbg',
    type: 'markets',
    number: 9479,
    name: 'Europe',
    facebook_pixel_id: null,
    checkout_url: '',
    external_prices_url: '',
    private: false,
    created_at: '2022-02-22T04:01:30.274Z',
    updated_at: '2022-05-31T08:58:18.202Z',
    reference: 'market_1',
    reference_origin: 'CLI',
    metadata: {}
  },
  {
    id: 'YlqxGhKrQg',
    type: 'markets',
    number: 9480,
    name: 'USA',
    facebook_pixel_id: null,
    checkout_url: '',
    external_prices_url: '',
    private: false,
    created_at: '2022-02-22T04:01:34.336Z',
    updated_at: '2022-05-31T08:57:24.446Z',
    reference: 'market_2',
    reference_origin: 'CLI',
    metadata: {}
  },
  {
    id: 'bgOEQhEyQo',
    type: 'markets',
    number: 9481,
    name: 'UK',
    facebook_pixel_id: null,
    checkout_url: '',
    external_prices_url: '',
    private: false,
    created_at: '2022-02-22T04:01:38.524Z',
    updated_at: '2022-05-31T08:58:10.390Z',
    reference: 'market_3',
    reference_origin: 'CLI',
    metadata: {}
  }
]
```

{% endtab %}
{% endtabs %}

#### Create a new order

Now you can create a new order for the market you selected:

{% tabs %}
{% tab title="CLI command" %}
The following command creates a new order and associates it with a market:

```shell
cl resources:create orders -r market=markets/QlNQVhWxbg
```

{% endtab %}

{% tab title="Response" %}
On successful run, the newly created order object information is prompted:

```javascript
{
  id: 'wjobhWrZka',
  type: 'orders',
  number: 28117000,
  autorefresh: true,
  status: 'draft',
  payment_status: 'unpaid',
  fulfillment_status: 'unfulfilled',
  guest: true,
  editable: true,
  customer_email: null,
  language_code: 'en',
  currency_code: 'EUR',
  tax_included: true,
  tax_rate: null,
  freight_taxable: null,
  requires_billing_info: false,
  country_code: null,
  shipping_country_code_lock: null,
  coupon_code: null,
  gift_card_code: null,
  gift_card_or_coupon_code: null,
  subtotal_amount_cents: 0,
  subtotal_amount_float: 0,
  formatted_subtotal_amount: '€0,00',
  shipping_amount_cents: 0,
  shipping_amount_float: 0,
  formatted_shipping_amount: '€0,00',
  payment_method_amount_cents: 0,
  payment_method_amount_float: 0,
  formatted_payment_method_amount: '€0,00',
  discount_amount_cents: 0,
  discount_amount_float: 0,
  formatted_discount_amount: '€0,00',
  adjustment_amount_cents: 0,
  adjustment_amount_float: 0,
  formatted_adjustment_amount: '€0,00',
  gift_card_amount_cents: 0,
  gift_card_amount_float: 0,
  formatted_gift_card_amount: '€0,00',
  total_tax_amount_cents: 0,
  total_tax_amount_float: 0,
  formatted_total_tax_amount: '€0,00',
  subtotal_tax_amount_cents: 0,
  subtotal_tax_amount_float: 0,
  formatted_subtotal_tax_amount: '€0,00',
  shipping_tax_amount_cents: 0,
  shipping_tax_amount_float: 0,
  formatted_shipping_tax_amount: '€0,00',
  payment_method_tax_amount_cents: 0,
  payment_method_tax_amount_float: 0,
  formatted_payment_method_tax_amount: '€0,00',
  adjustment_tax_amount_cents: 0,
  adjustment_tax_amount_float: 0,
  formatted_adjustment_tax_amount: '€0,00',
  total_amount_cents: 0,
  total_amount_float: 0,
  formatted_total_amount: '€0,00',
  total_taxable_amount_cents: 0,
  total_taxable_amount_float: 0,
  formatted_total_taxable_amount: '€0,00',
  subtotal_taxable_amount_cents: 0,
  subtotal_taxable_amount_float: 0,
  formatted_subtotal_taxable_amount: '€0,00',
  shipping_taxable_amount_cents: 0,
  shipping_taxable_amount_float: 0,
  formatted_shipping_taxable_amount: '€0,00',
  payment_method_taxable_amount_cents: 0,
  payment_method_taxable_amount_float: 0,
  formatted_payment_method_taxable_amount: '€0,00',
  adjustment_taxable_amount_cents: 0,
  adjustment_taxable_amount_float: 0,
  formatted_adjustment_taxable_amount: '€0,00',
  total_amount_with_taxes_cents: 0,
  total_amount_with_taxes_float: 0,
  formatted_total_amount_with_taxes: '€0,00',
  fees_amount_cents: 0,
  fees_amount_float: 0,
  formatted_fees_amount: '€0,00',
  duty_amount_cents: null,
  duty_amount_float: null,
  formatted_duty_amount: null,
  skus_count: 0,
  line_item_options_count: 0,
  shipments_count: 0,
  tax_calculations_count: 0,
  payment_source_details: null,
  token: '8dae3a32b28749d63d8edc0ab155797c',
  cart_url: null,
  return_url: null,
  terms_url: null,
  privacy_url: null,
  checkout_url: null,
  placed_at: null,
  approved_at: null,
  cancelled_at: null,
  payment_updated_at: null,
  fulfillment_updated_at: null,
  refreshed_at: null,
  archived_at: null,
  expires_at: '2022-12-03T19:11:30.589Z',
  created_at: '2022-10-03T19:11:30.582Z',
  updated_at: '2022-10-03T19:11:30.582Z',
  reference: null,
  reference_origin: null,
  metadata: {},
  market: {
    id: 'QlNQVhWxbg',
    type: 'markets',
    number: 9479,
    name: 'Europe',
    facebook_pixel_id: null,
    checkout_url: '',
    external_prices_url: '',
    private: false,
    created_at: '2022-02-22T04:01:30.274Z',
    updated_at: '2022-05-31T08:58:18.202Z',
    reference: 'market_1',
    reference_origin: 'CLI',
    metadata: {}
  }
}je
```

{% endtab %}
{% endtabs %}

#### Create a line item

Now you can add the SKU to the newly created order by associating the related line item. Use the `quantity` attribute to add multiple units of the same product:

{% tabs %}
{% tab title="CLI command" %}
The following command creates a line item and associates it with an order and an SKU:

```shell
cl resources:create line_items -a quantity=5 -r order=orders/wjobhWrZka -r item=skus/WKjRSOlEOP
```

{% endtab %}

{% tab title="Response" %}
On successful run, the newly created line item object information is prompted:

```javascript
{
  id: 'yKlZtAGoLP',
  type: 'line_items',
  sku_code: 'TSHIRTMSB0B0B2000000LXXX',
  bundle_code: null,
  quantity: 5,
  currency_code: 'EUR',
  unit_amount_cents: 3470,
  unit_amount_float: 34.7,
  formatted_unit_amount: '€34,70',
  options_amount_cents: 0,
  options_amount_float: 0,
  formatted_options_amount: '€0,00',
  discount_cents: 0,
  discount_float: 0,
  formatted_discount: '€0,00',
  total_amount_cents: 17350,
  total_amount_float: 173.5,
  formatted_total_amount: '€173,50',
  tax_amount_cents: 0,
  tax_amount_float: 0,
  formatted_tax_amount: '€0,00',
  name: 'Men's Gray T-Shirt with Black Logo (L)',
  image_url: 'https://data.commercelayer.app/seed/images/skus/TSHIRTMSB0B0B2000000LXXX_FLAT.png',
  discount_breakdown: {},
  tax_rate: 0,
  tax_breakdown: {},
  item_type: 'skus',
  created_at: '2022-10-03T19:17:11.883Z',
  updated_at: '2022-10-03T19:17:11.883Z',
  reference: null,
  reference_origin: null,
  metadata: {},
  order: {
    id: 'wjobhWrZka',
    type: 'orders',
    number: 28117000,
    autorefresh: true,
    status: 'draft',
    payment_status: 'unpaid',
    fulfillment_status: 'unfulfilled',
    guest: true,
    editable: true,
    customer_email: null,
    language_code: 'en',
    currency_code: 'EUR',
    tax_included: true,
    tax_rate: null,
    freight_taxable: null,
    requires_billing_info: false,
    country_code: null,
    shipping_country_code_lock: null,
    coupon_code: null,
    gift_card_code: null,
    gift_card_or_coupon_code: null,
    subtotal_amount_cents: 17350,
    subtotal_amount_float: 173.5,
    formatted_subtotal_amount: '€173,50',
    shipping_amount_cents: 0,
    shipping_amount_float: 0,
    formatted_shipping_amount: '€0,00',
    payment_method_amount_cents: 0,
    payment_method_amount_float: 0,
    formatted_payment_method_amount: '€0,00',
    discount_amount_cents: 0,
    discount_amount_float: 0,
    formatted_discount_amount: '€0,00',
    adjustment_amount_cents: 0,
    adjustment_amount_float: 0,
    formatted_adjustment_amount: '€0,00',
    gift_card_amount_cents: 0,
    gift_card_amount_float: 0,
    formatted_gift_card_amount: '€0,00',
    total_tax_amount_cents: 0,
    total_tax_amount_float: 0,
    formatted_total_tax_amount: '€0,00',
    subtotal_tax_amount_cents: 0,
    subtotal_tax_amount_float: 0,
    formatted_subtotal_tax_amount: '€0,00',
    shipping_tax_amount_cents: 0,
    shipping_tax_amount_float: 0,
    formatted_shipping_tax_amount: '€0,00',
    payment_method_tax_amount_cents: 0,
    payment_method_tax_amount_float: 0,
    formatted_payment_method_tax_amount: '€0,00',
    adjustment_tax_amount_cents: 0,
    adjustment_tax_amount_float: 0,
    formatted_adjustment_tax_amount: '€0,00',
    total_amount_cents: 17350,
    total_amount_float: 173.5,
    formatted_total_amount: '€173,50',
    total_taxable_amount_cents: 17350,
    total_taxable_amount_float: 173.5,
    formatted_total_taxable_amount: '€173,50',
    subtotal_taxable_amount_cents: 17350,
    subtotal_taxable_amount_float: 173.5,
    formatted_subtotal_taxable_amount: '€173,50',
    shipping_taxable_amount_cents: 0,
    shipping_taxable_amount_float: 0,
    formatted_shipping_taxable_amount: '€0,00',
    payment_method_taxable_amount_cents: 0,
    payment_method_taxable_amount_float: 0,
    formatted_payment_method_taxable_amount: '€0,00',
    adjustment_taxable_amount_cents: 0,
    adjustment_taxable_amount_float: 0,
    formatted_adjustment_taxable_amount: '€0,00',
    total_amount_with_taxes_cents: 17350,
    total_amount_with_taxes_float: 173.5,
    formatted_total_amount_with_taxes: '€173,50',
    fees_amount_cents: 0,
    fees_amount_float: 0,
    formatted_fees_amount: '€0,00',
    duty_amount_cents: null,
    duty_amount_float: null,
    formatted_duty_amount: null,
    skus_count: 5,
    line_item_options_count: 0,
    shipments_count: 0,
    tax_calculations_count: 0,
    payment_source_details: null,
    token: '8dae3a32b28749d63d8edc0ab155797c',
    cart_url: null,
    return_url: null,
    terms_url: null,
    privacy_url: null,
    checkout_url: null,
    placed_at: null,
    approved_at: null,
    cancelled_at: null,
    payment_updated_at: null,
    fulfillment_updated_at: null,
    refreshed_at: null,
    archived_at: null,
    expires_at: null,
    created_at: '2022-10-03T19:11:30.582Z',
    updated_at: '2022-10-03T19:17:11.895Z',
    reference: null,
    reference_origin: null,
    metadata: {}
  },
  item: {
    id: 'WKjRSOlEOP',
    type: 'skus',
    code: 'TSHIRTMSB0B0B2000000LXXX',
    name: 'Men's Gray T-Shirt with Black Logo (L)',
    description: "This is THE classic t-shirt. Its fine jersey cotton construction makes it extremely soft and comfortable to wear, so it's a good choice for a day-to-day outfit — it's durable and can withstand several washings while retaining its shape and color.",
    image_url: 'https://data.commercelayer.app/seed/images/skus/TSHIRTMSB0B0B2000000LXXX_FLAT.png',
    pieces_per_pack: null,
    weight: null,
    unit_of_weight: null,
    hs_tariff_number: null,
    do_not_ship: false,
    do_not_track: false,
    created_at: '2022-02-22T04:13:02.232Z',
    updated_at: '2022-02-22T04:13:02.232Z',
    reference: 'sku_219',
    reference_origin: 'CLI',
    metadata: {}
  }
}
```

{% endtab %}
{% endtabs %}

#### Assign the order to a customer

The order must now be updated to be associated with a customer using the customer's email:

{% tabs %}
{% tab title="CLI command" %}
The following command associates a customer email with an order:

```shell
cl resources:update orders/wjobhWrZka -a customer_email=bolaji@commercelayer.io
```

{% endtab %}

{% tab title="Response" %}
On successful run, the updated order object information is prompted:

```javascript
{
  id: 'wjobhWrZka',
  type: 'orders',
  number: 28117000,
  autorefresh: true,
  status: 'pending',
  payment_status: 'unpaid',
  fulfillment_status: 'unfulfilled',
  guest: true,
  editable: true,
  customer_email: 'bolaji@commercelayer.io',
  language_code: 'en',
  currency_code: 'EUR',
  tax_included: true,
  tax_rate: null,
  freight_taxable: null,
  requires_billing_info: false,
  country_code: null,
  shipping_country_code_lock: null,
  coupon_code: null,
  gift_card_code: null,
  gift_card_or_coupon_code: null,
  subtotal_amount_cents: 17350,
  subtotal_amount_float: 173.5,
  formatted_subtotal_amount: '€173,50',
  shipping_amount_cents: 0,
  shipping_amount_float: 0,
  formatted_shipping_amount: '€0,00',
  payment_method_amount_cents: 0,
  payment_method_amount_float: 0,
  formatted_payment_method_amount: '€0,00',
  discount_amount_cents: 0,
  discount_amount_float: 0,
  formatted_discount_amount: '€0,00',
  adjustment_amount_cents: 0,
  adjustment_amount_float: 0,
  formatted_adjustment_amount: '€0,00',
  gift_card_amount_cents: 0,
  gift_card_amount_float: 0,
  formatted_gift_card_amount: '€0,00',
  total_tax_amount_cents: 0,
  total_tax_amount_float: 0,
  formatted_total_tax_amount: '€0,00',
  subtotal_tax_amount_cents: 0,
  subtotal_tax_amount_float: 0,
  formatted_subtotal_tax_amount: '€0,00',
  shipping_tax_amount_cents: 0,
  shipping_tax_amount_float: 0,
  formatted_shipping_tax_amount: '€0,00',
  payment_method_tax_amount_cents: 0,
  payment_method_tax_amount_float: 0,
  formatted_payment_method_tax_amount: '€0,00',
  adjustment_tax_amount_cents: 0,
  adjustment_tax_amount_float: 0,
  formatted_adjustment_tax_amount: '€0,00',
  total_amount_cents: 17350,
  total_amount_float: 173.5,
  formatted_total_amount: '€173,50',
  total_taxable_amount_cents: 17350,
  total_taxable_amount_float: 173.5,
  formatted_total_taxable_amount: '€173,50',
  subtotal_taxable_amount_cents: 17350,
  subtotal_taxable_amount_float: 173.5,
  formatted_subtotal_taxable_amount: '€173,50',
  shipping_taxable_amount_cents: 0,
  shipping_taxable_amount_float: 0,
  formatted_shipping_taxable_amount: '€0,00',
  payment_method_taxable_amount_cents: 0,
  payment_method_taxable_amount_float: 0,
  formatted_payment_method_taxable_amount: '€0,00',
  adjustment_taxable_amount_cents: 0,
  adjustment_taxable_amount_float: 0,
  formatted_adjustment_taxable_amount: '€0,00',
  total_amount_with_taxes_cents: 17350,
  total_amount_with_taxes_float: 173.5,
  formatted_total_amount_with_taxes: '€173,50',
  fees_amount_cents: 0,
  fees_amount_float: 0,
  formatted_fees_amount: '€0,00',
  duty_amount_cents: null,
  duty_amount_float: null,
  formatted_duty_amount: null,
  skus_count: 5,
  line_item_options_count: 0,
  shipments_count: 0,
  tax_calculations_count: 0,
  payment_source_details: null,
  token: '8dae3a32b28749d63d8edc0ab155797c',
  cart_url: null,
  return_url: null,
  terms_url: null,
  privacy_url: null,
  checkout_url: null,
  placed_at: null,
  approved_at: null,
  cancelled_at: null,
  payment_updated_at: null,
  fulfillment_updated_at: null,
  refreshed_at: null,
  archived_at: null,
  expires_at: null,
  created_at: '2022-10-03T19:11:30.582Z',
  updated_at: '2022-10-04T02:19:14.615Z',
  reference: null,
  reference_origin: null,
  metadata: {}
}
```

{% endtab %}
{% endtabs %}

#### Create an address

Now you need to create an address that will be use used to checkout the order:

{% tabs %}
{% tab title="CLI command" %}
The following command creates a new address:

```shell
cl resources:create addresses -a first_name=Bolaji last_name=Ayodeji line_1="Undefined Street, Commerce Rd" line_2="Lorem Ipsum" city=Florence state_code=FI country_code=IT phone=33812345678 zip_code=50100
```

{% endtab %}

{% tab title="Response" %}
On successful run, the created address object information is prompted:

```javascript
{
  id: 'BvoVuxgyvk',
  type: 'addresses',
  business: false,
  first_name: 'Bolaji',
  last_name: 'Ayodeji',
  company: null,
  full_name: 'Bolaji Ayodeji',
  line_1: 'Undefined Street, Commerce Rd',
  line_2: 'Lorem Ipsum',
  city: 'Florence',
  zip_code: '50100',
  state_code: 'FI',
  country_code: 'IT',
  phone: '33812345678',
  full_address: 'Undefined Street, Commerce Rd Lorem Ipsum, 50100 Florence FI (IT) 33812345678',
  name: 'Bolaji Ayodeji, Undefined Street, Commerce Rd Lorem Ipsum, 50100 Florence FI (IT) 33812345678',
  email: null,
  notes: null,
  lat: null,
  lng: null,
  is_localized: false,
  is_geocoded: false,
  provider_name: null,
  map_url: null,
  static_map_url: null,
  billing_info: null,
  created_at: '2022-10-04T02:38:22.195Z',
  updated_at: '2022-10-04T02:38:22.195Z',
  reference: null,
  reference_origin: null,
  metadata: {}
}

```

{% endtab %}
{% endtabs %}

#### Update the order with a shipping and billing address

The previously created address will be used both as the billing and the shipping address of the order:

{% tabs %}
{% tab title="CLI command" %}
The following command associates a shipping and billing address with an order:

```shell
cl resources:update orders/wjobhWrZka -r billing_address=addresses/BvoVuxgyvk shipping_address=addresses/BvoVuxgyvk
```

{% endtab %}

{% tab title="Response" %}
On successful run, the updated order object information is prompted:

```javascript
{
  id: 'wjobhWrZka',
  type: 'orders',
  number: 28117000,
  autorefresh: true,
  status: 'pending',
  payment_status: 'unpaid',
  fulfillment_status: 'unfulfilled',
  guest: true,
  editable: true,
  customer_email: 'bolaji@commercelayer.io',
  language_code: 'en',
  currency_code: 'EUR',
  tax_included: true,
  tax_rate: null,
  freight_taxable: null,
  requires_billing_info: false,
  country_code: 'IT',
  shipping_country_code_lock: null,
  coupon_code: null,
  gift_card_code: null,
  gift_card_or_coupon_code: null,
  subtotal_amount_cents: 17350,
  subtotal_amount_float: 173.5,
  formatted_subtotal_amount: '€173,50',
  shipping_amount_cents: 0,
  shipping_amount_float: 0,
  formatted_shipping_amount: '€0,00',
  payment_method_amount_cents: 0,
  payment_method_amount_float: 0,
  formatted_payment_method_amount: '€0,00',
  discount_amount_cents: 0,
  discount_amount_float: 0,
  formatted_discount_amount: '€0,00',
  adjustment_amount_cents: 0,
  adjustment_amount_float: 0,
  formatted_adjustment_amount: '€0,00',
  gift_card_amount_cents: 0,
  gift_card_amount_float: 0,
  formatted_gift_card_amount: '€0,00',
  total_tax_amount_cents: 0,
  total_tax_amount_float: 0,
  formatted_total_tax_amount: '€0,00',
  subtotal_tax_amount_cents: 0,
  subtotal_tax_amount_float: 0,
  formatted_subtotal_tax_amount: '€0,00',
  shipping_tax_amount_cents: 0,
  shipping_tax_amount_float: 0,
  formatted_shipping_tax_amount: '€0,00',
  payment_method_tax_amount_cents: 0,
  payment_method_tax_amount_float: 0,
  formatted_payment_method_tax_amount: '€0,00',
  adjustment_tax_amount_cents: 0,
  adjustment_tax_amount_float: 0,
  formatted_adjustment_tax_amount: '€0,00',
  total_amount_cents: 17350,
  total_amount_float: 173.5,
  formatted_total_amount: '€173,50',
  total_taxable_amount_cents: 17350,
  total_taxable_amount_float: 173.5,
  formatted_total_taxable_amount: '€173,50',
  subtotal_taxable_amount_cents: 17350,
  subtotal_taxable_amount_float: 173.5,
  formatted_subtotal_taxable_amount: '€173,50',
  shipping_taxable_amount_cents: 0,
  shipping_taxable_amount_float: 0,
  formatted_shipping_taxable_amount: '€0,00',
  payment_method_taxable_amount_cents: 0,
  payment_method_taxable_amount_float: 0,
  formatted_payment_method_taxable_amount: '€0,00',
  adjustment_taxable_amount_cents: 0,
  adjustment_taxable_amount_float: 0,
  formatted_adjustment_taxable_amount: '€0,00',
  total_amount_with_taxes_cents: 17350,
  total_amount_with_taxes_float: 173.5,
  formatted_total_amount_with_taxes: '€173,50',
  fees_amount_cents: 0,
  fees_amount_float: 0,
  formatted_fees_amount: '€0,00',
  duty_amount_cents: null,
  duty_amount_float: null,
  formatted_duty_amount: null,
  skus_count: 5,
  line_item_options_count: 0,
  shipments_count: 1,
  tax_calculations_count: 0,
  payment_source_details: null,
  token: '8dae3a32b28749d63d8edc0ab155797c',
  cart_url: null,
  return_url: null,
  terms_url: null,
  privacy_url: null,
  checkout_url: null,
  placed_at: null,
  approved_at: null,
  cancelled_at: null,
  payment_updated_at: null,
  fulfillment_updated_at: null,
  refreshed_at: null,
  archived_at: null,
  expires_at: null,
  created_at: '2022-10-03T19:11:30.582Z',
  updated_at: '2022-10-04T02:42:57.246Z',
  reference: null,
  reference_origin: null,
  metadata: {},
  shipping_address: {
    id: 'BvoVuxgyvk',
    type: 'addresses',
    business: false,
    first_name: 'Bolaji',
    last_name: 'Ayodeji',
    company: null,
    full_name: 'Bolaji Ayodeji',
    line_1: 'Undefined Street, Commerce Rd',
    line_2: 'Lorem Ipsum',
    city: 'Florence',
    zip_code: '50100',
    state_code: 'FI',
    country_code: 'IT',
    phone: '33812345678',
    full_address: 'Undefined Street, Commerce Rd Lorem Ipsum, 50100 Florence FI (IT) 33812345678',
    name: 'Bolaji Ayodeji, Undefined Street, Commerce Rd Lorem Ipsum, 50100 Florence FI (IT) 33812345678',
    email: null,
    notes: null,
    lat: null,
    lng: null,
    is_localized: false,
    is_geocoded: false,
    provider_name: null,
    map_url: null,
    static_map_url: null,
    billing_info: null,
    created_at: '2022-10-04T02:38:22.195Z',
    updated_at: '2022-10-04T02:38:22.195Z',
    reference: null,
    reference_origin: null,
    metadata: {}
  },
  billing_address: {
    id: 'BvoVuxgyvk',
    type: 'addresses',
    business: false,
    first_name: 'Bolaji',
    last_name: 'Ayodeji',
    company: null,
    full_name: 'Bolaji Ayodeji',
    line_1: 'Undefined Street, Commerce Rd',
    line_2: 'Lorem Ipsum',
    city: 'Florence',
    zip_code: '50100',
    state_code: 'FI',
    country_code: 'IT',
    phone: '33812345678',
    full_address: 'Undefined Street, Commerce Rd Lorem Ipsum, 50100 Florence FI (IT) 33812345678',
    name: 'Bolaji Ayodeji, Undefined Street, Commerce Rd Lorem Ipsum, 50100 Florence FI (IT) 33812345678',
    email: null,
    notes: null,
    lat: null,
    lng: null,
    is_localized: false,
    is_geocoded: false,
    provider_name: null,
    map_url: null,
    static_map_url: null,
    billing_info: null,
    created_at: '2022-10-04T02:38:22.195Z',
    updated_at: '2022-10-04T02:38:22.195Z',
    reference: null,
    reference_origin: null,
    metadata: {}
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
You can associate different addresses for shipping and billing. All you need to do is create another address as described in the [previous step](#create-an-address) and associate the ID here.
{% endhint %}

#### Get the order shipments and the available shipping methods

To choose a shipping method for the shipment(s) associated with your order, you need first to check what are the available ones:

{% tabs %}
{% tab title="CLI command" %}
The following command fetches the shipments associated with an order and all the available shipping methods:

```shell
cl resources:get orders wjobhWrZka -i shipments,shipments.available_shipping_methods
```

{% endtab %}

{% tab title="Response" %}
On successful run, the order object information (with shipments and shipping methods) is prompted:

```javascript
{
  id: 'wjobhWrZka',
  type: 'orders',
  number: 28117000,
  autorefresh: true,
  status: 'pending',
  payment_status: 'unpaid',
  fulfillment_status: 'unfulfilled',
  guest: true,
  editable: true,
  customer_email: 'bolaji@commercelayer.io',
  language_code: 'en',
  currency_code: 'EUR',
  tax_included: true,
  tax_rate: null,
  freight_taxable: null,
  requires_billing_info: false,
  country_code: 'IT',
  shipping_country_code_lock: null,
  coupon_code: null,
  gift_card_code: null,
  gift_card_or_coupon_code: null,
  subtotal_amount_cents: 17350,
  subtotal_amount_float: 173.5,
  formatted_subtotal_amount: '€173,50',
  shipping_amount_cents: 0,
  shipping_amount_float: 0,
  formatted_shipping_amount: '€0,00',
  payment_method_amount_cents: 0,
  payment_method_amount_float: 0,
  formatted_payment_method_amount: '€0,00',
  discount_amount_cents: 0,
  discount_amount_float: 0,
  formatted_discount_amount: '€0,00',
  adjustment_amount_cents: 0,
  adjustment_amount_float: 0,
  formatted_adjustment_amount: '€0,00',
  gift_card_amount_cents: 0,
  gift_card_amount_float: 0,
  formatted_gift_card_amount: '€0,00',
  total_tax_amount_cents: 0,
  total_tax_amount_float: 0,
  formatted_total_tax_amount: '€0,00',
  subtotal_tax_amount_cents: 0,
  subtotal_tax_amount_float: 0,
  formatted_subtotal_tax_amount: '€0,00',
  shipping_tax_amount_cents: 0,
  shipping_tax_amount_float: 0,
  formatted_shipping_tax_amount: '€0,00',
  payment_method_tax_amount_cents: 0,
  payment_method_tax_amount_float: 0,
  formatted_payment_method_tax_amount: '€0,00',
  adjustment_tax_amount_cents: 0,
  adjustment_tax_amount_float: 0,
  formatted_adjustment_tax_amount: '€0,00',
  total_amount_cents: 17350,
  total_amount_float: 173.5,
  formatted_total_amount: '€173,50',
  total_taxable_amount_cents: 17350,
  total_taxable_amount_float: 173.5,
  formatted_total_taxable_amount: '€173,50',
  subtotal_taxable_amount_cents: 17350,
  subtotal_taxable_amount_float: 173.5,
  formatted_subtotal_taxable_amount: '€173,50',
  shipping_taxable_amount_cents: 0,
  shipping_taxable_amount_float: 0,
  formatted_shipping_taxable_amount: '€0,00',
  payment_method_taxable_amount_cents: 0,
  payment_method_taxable_amount_float: 0,
  formatted_payment_method_taxable_amount: '€0,00',
  adjustment_taxable_amount_cents: 0,
  adjustment_taxable_amount_float: 0,
  formatted_adjustment_taxable_amount: '€0,00',
  total_amount_with_taxes_cents: 17350,
  total_amount_with_taxes_float: 173.5,
  formatted_total_amount_with_taxes: '€173,50',
  fees_amount_cents: 0,
  fees_amount_float: 0,
  formatted_fees_amount: '€0,00',
  duty_amount_cents: null,
  duty_amount_float: null,
  formatted_duty_amount: null,
  skus_count: 5,
  line_item_options_count: 0,
  shipments_count: 1,
  tax_calculations_count: 0,
  payment_source_details: null,
  token: '8dae3a32b28749d63d8edc0ab155797c',
  cart_url: null,
  return_url: null,
  terms_url: null,
  privacy_url: null,
  checkout_url: null,
  placed_at: null,
  approved_at: null,
  cancelled_at: null,
  payment_updated_at: null,
  fulfillment_updated_at: null,
  refreshed_at: null,
  archived_at: null,
  expires_at: null,
  created_at: '2022-10-03T19:11:30.582Z',
  updated_at: '2022-10-04T02:42:57.246Z',
  reference: null,
  reference_origin: null,
  metadata: {},
  shipments: [
    {
      id: 'PabvCqgnAw',
      type: 'shipments',
      number: '28117000/S/001',
      status: 'draft',
      currency_code: 'EUR',
      cost_amount_cents: 0,
      cost_amount_float: 0,
      formatted_cost_amount: '$0.00',
      skus_count: 5,
      selected_rate_id: null,
      rates: [],
      purchase_error_code: null,
      purchase_error_message: null,
      get_rates_errors: [],
      get_rates_started_at: null,
      get_rates_completed_at: null,
      purchase_started_at: null,
      purchase_completed_at: null,
      purchase_failed_at: null,
      created_at: '2022-10-04T02:42:57.233Z',
      updated_at: '2022-10-04T02:42:57.233Z',
      reference: null,
      reference_origin: null,
      metadata: {},
      available_shipping_methods: [
        {
          id: 'wEvWBFqejO',
          type: 'shipping_methods',
          name: 'Standard Shipping',
          scheme: 'flat',
          currency_code: 'EUR',
          disabled_at: null,
          price_amount_cents: 700,
          price_amount_float: 7,
          formatted_price_amount: '€7,00',
          free_over_amount_cents: 9900,
          free_over_amount_float: 99,
          formatted_free_over_amount: '€99,00',
          price_amount_for_shipment_cents: 0,
          price_amount_for_shipment_float: 0,
          formatted_price_amount_for_shipment: '€0,00',
          min_weight: null,
          max_weight: null,
          unit_of_weight: null,
          created_at: '2022-02-22T04:01:53.103Z',
          updated_at: '2022-02-22T04:01:53.103Z',
          reference: 'shipping_method_1',
          reference_origin: 'CLI',
          metadata: {}
        },
        {
          id: 'XOzWbFmJyN',
          type: 'shipping_methods',
          name: 'Express Delivery',
          scheme: 'flat',
          currency_code: 'EUR',
          disabled_at: null,
          price_amount_cents: 1200,
          price_amount_float: 12,
          formatted_price_amount: '€12,00',
          free_over_amount_cents: null,
          free_over_amount_float: null,
          formatted_free_over_amount: null,
          price_amount_for_shipment_cents: 1200,
          price_amount_for_shipment_float: 12,
          formatted_price_amount_for_shipment: '€12,00',
          min_weight: null,
          max_weight: null,
          unit_of_weight: null,
          created_at: '2022-02-22T04:01:57.142Z',
          updated_at: '2022-02-22T04:01:57.142Z',
          reference: 'shipping_method_2',
          reference_origin: 'CLI',
          metadata: {}
        }
      ]
    }
  ]
}
```

{% endtab %}
{% endtabs %}

#### Update the shipment with a shipping method

Now you can associate the desired shipping method with the shipment:

{% tabs %}
{% tab title="CLI command" %}
The following command associates a selected shipping method with a shipment:

```shell
cl resources:update shipments/PabvCqgnAw -r shipping_method=shipping_methods/XOzWbFmJyN
```

{% endtab %}

{% tab title="Response" %}
On successful run, the updated shipments object information is prompted:

```javascript
{
  id: 'PabvCqgnAw',
  type: 'shipments',
  number: '28117000/S/001',
  status: 'draft',
  currency_code: 'EUR',
  cost_amount_cents: 0,
  cost_amount_float: 0,
  formatted_cost_amount: '$0.00',
  skus_count: 5,
  selected_rate_id: null,
  rates: [],
  purchase_error_code: null,
  purchase_error_message: null,
  get_rates_errors: [],
  get_rates_started_at: null,
  get_rates_completed_at: null,
  purchase_started_at: null,
  purchase_completed_at: null,
  purchase_failed_at: null,
  created_at: '2022-10-04T02:42:57.233Z',
  updated_at: '2022-10-04T03:00:42.015Z',
  reference: null,
  reference_origin: null,
  metadata: {},
  shipping_method: {
    id: 'XOzWbFmJyN',
    type: 'shipping_methods',
    name: 'Express Delivery',
    scheme: 'flat',
    currency_code: 'EUR',
    disabled_at: null,
    price_amount_cents: 1200,
    price_amount_float: 12,
    formatted_price_amount: '€12,00',
    free_over_amount_cents: null,
    free_over_amount_float: null,
    formatted_free_over_amount: null,
    price_amount_for_shipment_cents: 1200,
    price_amount_for_shipment_float: 12,
    formatted_price_amount_for_shipment: '€12,00',
    min_weight: null,
    max_weight: null,
    unit_of_weight: null,
    created_at: '2022-02-22T04:01:57.142Z',
    updated_at: '2022-02-22T04:01:57.142Z',
    reference: 'shipping_method_2',
    reference_origin: 'CLI',
    metadata: {}
  }
}
```

{% endtab %}
{% endtabs %}

#### Get the available payment methods

To choose a payment method for your order, you need first to check what are the available ones:

{% tabs %}
{% tab title="CLI command" %}
The following command fetches the payment methods associated with an order:

```shell
cl resources:get orders wjobhWrZka -i available_payment_methods
```

{% endtab %}

{% tab title="Response" %}
On successful run, the order object information (with the available payment methods) is prompted:

```javascript
{
  id: 'wjobhWrZka',
  type: 'orders',
  number: 28117000,
  autorefresh: true,
  status: 'pending',
  payment_status: 'unpaid',
  fulfillment_status: 'unfulfilled',
  guest: true,
  editable: true,
  customer_email: 'bolaji@commercelayer.io',
  language_code: 'en',
  currency_code: 'EUR',
  tax_included: true,
  tax_rate: null,
  freight_taxable: null,
  requires_billing_info: false,
  country_code: 'IT',
  shipping_country_code_lock: null,
  coupon_code: null,
  gift_card_code: null,
  gift_card_or_coupon_code: null,
  subtotal_amount_cents: 17350,
  subtotal_amount_float: 173.5,
  formatted_subtotal_amount: '€173,50',
  shipping_amount_cents: 1200,
  shipping_amount_float: 12,
  formatted_shipping_amount: '€12,00',
  payment_method_amount_cents: 0,
  payment_method_amount_float: 0,
  formatted_payment_method_amount: '€0,00',
  discount_amount_cents: 0,
  discount_amount_float: 0,
  formatted_discount_amount: '€0,00',
  adjustment_amount_cents: 0,
  adjustment_amount_float: 0,
  formatted_adjustment_amount: '€0,00',
  gift_card_amount_cents: 0,
  gift_card_amount_float: 0,
  formatted_gift_card_amount: '€0,00',
  total_tax_amount_cents: 0,
  total_tax_amount_float: 0,
  formatted_total_tax_amount: '€0,00',
  subtotal_tax_amount_cents: 0,
  subtotal_tax_amount_float: 0,
  formatted_subtotal_tax_amount: '€0,00',
  shipping_tax_amount_cents: 0,
  shipping_tax_amount_float: 0,
  formatted_shipping_tax_amount: '€0,00',
  payment_method_tax_amount_cents: 0,
  payment_method_tax_amount_float: 0,
  formatted_payment_method_tax_amount: '€0,00',
  adjustment_tax_amount_cents: 0,
  adjustment_tax_amount_float: 0,
  formatted_adjustment_tax_amount: '€0,00',
  total_amount_cents: 18550,
  total_amount_float: 185.5,
  formatted_total_amount: '€185,50',
  total_taxable_amount_cents: 18550,
  total_taxable_amount_float: 185.5,
  formatted_total_taxable_amount: '€185,50',
  subtotal_taxable_amount_cents: 17350,
  subtotal_taxable_amount_float: 173.5,
  formatted_subtotal_taxable_amount: '€173,50',
  shipping_taxable_amount_cents: 1200,
  shipping_taxable_amount_float: 12,
  formatted_shipping_taxable_amount: '€12,00',
  payment_method_taxable_amount_cents: 0,
  payment_method_taxable_amount_float: 0,
  formatted_payment_method_taxable_amount: '€0,00',
  adjustment_taxable_amount_cents: 0,
  adjustment_taxable_amount_float: 0,
  formatted_adjustment_taxable_amount: '€0,00',
  total_amount_with_taxes_cents: 18550,
  total_amount_with_taxes_float: 185.5,
  formatted_total_amount_with_taxes: '€185,50',
  fees_amount_cents: 0,
  fees_amount_float: 0,
  formatted_fees_amount: '€0,00',
  duty_amount_cents: null,
  duty_amount_float: null,
  formatted_duty_amount: null,
  skus_count: 5,
  line_item_options_count: 0,
  shipments_count: 1,
  tax_calculations_count: 0,
  payment_source_details: null,
  token: '8dae3a32b28749d63d8edc0ab155797c',
  cart_url: null,
  return_url: null,
  terms_url: null,
  privacy_url: null,
  checkout_url: null,
  placed_at: null,
  approved_at: null,
  cancelled_at: null,
  payment_updated_at: null,
  fulfillment_updated_at: null,
  refreshed_at: null,
  archived_at: null,
  expires_at: null,
  created_at: '2022-10-03T19:11:30.582Z',
  updated_at: '2022-10-04T03:00:42.030Z',
  reference: null,
  reference_origin: null,
  metadata: {},
  available_payment_methods: [
    {
      id: 'qMgwNsoxaM',
      type: 'payment_methods',
      payment_source_type: 'wire_transfers',
      name: 'Wire Transfer',
      currency_code: 'EUR',
      moto: false,
      disabled_at: null,
      price_amount_cents: 0,
      price_amount_float: 0,
      formatted_price_amount: '€0,00',
      created_at: '2022-02-22T04:02:13.694Z',
      updated_at: '2022-02-22T04:02:13.694Z',
      reference: 'payment_method_1',
      reference_origin: 'CLI',
      metadata: {}
    }
  ]
}
```

{% endtab %}
{% endtabs %}

#### Update the order with a payment methods

Now you can associate the desired payment method with the order:

{% tabs %}
{% tab title="CLI Command" %}
The following command associates a selected payment method with an order:

```shell
cl resources:update orders/wjobhWrZka -r payment_method=payment_methods/qMgwNsoxaM
```

{% endtab %}

{% tab title="Response" %}
On successful run, the updated order object information is prompted:

```javascript
{
  id: 'wjobhWrZka',
  type: 'orders',
  number: 28117000,
  autorefresh: true,
  status: 'pending',
  payment_status: 'unpaid',
  fulfillment_status: 'unfulfilled',
  guest: true,
  editable: true,
  customer_email: 'bolaji@commercelayer.io',
  language_code: 'en',
  currency_code: 'EUR',
  tax_included: true,
  tax_rate: null,
  freight_taxable: null,
  requires_billing_info: false,
  country_code: 'IT',
  shipping_country_code_lock: null,
  coupon_code: null,
  gift_card_code: null,
  gift_card_or_coupon_code: null,
  subtotal_amount_cents: 17350,
  subtotal_amount_float: 173.5,
  formatted_subtotal_amount: '€173,50',
  shipping_amount_cents: 1200,
  shipping_amount_float: 12,
  formatted_shipping_amount: '€12,00',
  payment_method_amount_cents: 0,
  payment_method_amount_float: 0,
  formatted_payment_method_amount: '€0,00',
  discount_amount_cents: 0,
  discount_amount_float: 0,
  formatted_discount_amount: '€0,00',
  adjustment_amount_cents: 0,
  adjustment_amount_float: 0,
  formatted_adjustment_amount: '€0,00',
  gift_card_amount_cents: 0,
  gift_card_amount_float: 0,
  formatted_gift_card_amount: '€0,00',
  total_tax_amount_cents: 0,
  total_tax_amount_float: 0,
  formatted_total_tax_amount: '€0,00',
  subtotal_tax_amount_cents: 0,
  subtotal_tax_amount_float: 0,
  formatted_subtotal_tax_amount: '€0,00',
  shipping_tax_amount_cents: 0,
  shipping_tax_amount_float: 0,
  formatted_shipping_tax_amount: '€0,00',
  payment_method_tax_amount_cents: 0,
  payment_method_tax_amount_float: 0,
  formatted_payment_method_tax_amount: '€0,00',
  adjustment_tax_amount_cents: 0,
  adjustment_tax_amount_float: 0,
  formatted_adjustment_tax_amount: '€0,00',
  total_amount_cents: 18550,
  total_amount_float: 185.5,
  formatted_total_amount: '€185,50',
  total_taxable_amount_cents: 18550,
  total_taxable_amount_float: 185.5,
  formatted_total_taxable_amount: '€185,50',
  subtotal_taxable_amount_cents: 17350,
  subtotal_taxable_amount_float: 173.5,
  formatted_subtotal_taxable_amount: '€173,50',
  shipping_taxable_amount_cents: 1200,
  shipping_taxable_amount_float: 12,
  formatted_shipping_taxable_amount: '€12,00',
  payment_method_taxable_amount_cents: 0,
  payment_method_taxable_amount_float: 0,
  formatted_payment_method_taxable_amount: '€0,00',
  adjustment_taxable_amount_cents: 0,
  adjustment_taxable_amount_float: 0,
  formatted_adjustment_taxable_amount: '€0,00',
  total_amount_with_taxes_cents: 18550,
  total_amount_with_taxes_float: 185.5,
  formatted_total_amount_with_taxes: '€185,50',
  fees_amount_cents: 0,
  fees_amount_float: 0,
  formatted_fees_amount: '€0,00',
  duty_amount_cents: null,
  duty_amount_float: null,
  formatted_duty_amount: null,
  skus_count: 5,
  line_item_options_count: 0,
  shipments_count: 1,
  tax_calculations_count: 0,
  payment_source_details: null,
  token: '8dae3a32b28749d63d8edc0ab155797c',
  cart_url: null,
  return_url: null,
  terms_url: null,
  privacy_url: null,
  checkout_url: null,
  placed_at: null,
  approved_at: null,
  cancelled_at: null,
  payment_updated_at: null,
  fulfillment_updated_at: null,
  refreshed_at: null,
  archived_at: null,
  expires_at: null,
  created_at: '2022-10-03T19:11:30.582Z',
  updated_at: '2022-10-04T03:08:27.260Z',
  reference: null,
  reference_origin: null,
  metadata: {},
  payment_method: {
    id: 'qMgwNsoxaM',
    type: 'payment_methods',
    payment_source_type: 'wire_transfers',
    name: 'Wire Transfer',
    currency_code: 'EUR',
    moto: false,
    disabled_at: null,
    price_amount_cents: 0,
    price_amount_float: 0,
    formatted_price_amount: '€0,00',
    created_at: '2022-02-22T04:02:13.694Z',
    updated_at: '2022-02-22T04:02:13.694Z',
    reference: 'payment_method_1',
    reference_origin: 'CLI',
    metadata: {}
  }
}
```

{% endtab %}
{% endtabs %}

#### Update the order with a payment source

To place the order you need now to create a [payment source type](https://docs.commercelayer.io/core/v/how-tos/checkout/selecting-a-payment-method#payment-source-types) related to the selected payment method:

{% tabs %}
{% tab title="CLI command" %}
The following command creates a wire transfer payment source type and associates it with an order:

```shell
cl resources:create wire_transfer -r order=orders/wjobhWrZka
```

{% endtab %}

{% tab title="Response" %}
On successful run, the newly created payment source type object information is prompted:

```javascript
{
  id: 'OAbkTVPePn',
  type: 'wire_transfers',
  created_at: '2022-10-04T03:16:34.288Z',
  updated_at: '2022-10-04T03:16:34.288Z',
  reference: null,
  reference_origin: null,
  metadata: {},
  order: {
    id: 'wjobhWrZka',
    type: 'orders',
    number: 28117000,
    autorefresh: true,
    status: 'pending',
    payment_status: 'unpaid',
    fulfillment_status: 'unfulfilled',
    guest: true,
    editable: true,
    customer_email: 'bolaji@commercelayer.io',
    language_code: 'en',
    currency_code: 'EUR',
    tax_included: true,
    tax_rate: null,
    freight_taxable: null,
    requires_billing_info: false,
    country_code: 'IT',
    shipping_country_code_lock: null,
    coupon_code: null,
    gift_card_code: null,
    gift_card_or_coupon_code: null,
    subtotal_amount_cents: 17350,
    subtotal_amount_float: 173.5,
    formatted_subtotal_amount: '€173,50',
    shipping_amount_cents: 1200,
    shipping_amount_float: 12,
    formatted_shipping_amount: '€12,00',
    payment_method_amount_cents: 0,
    payment_method_amount_float: 0,
    formatted_payment_method_amount: '€0,00',
    discount_amount_cents: 0,
    discount_amount_float: 0,
    formatted_discount_amount: '€0,00',
    adjustment_amount_cents: 0,
    adjustment_amount_float: 0,
    formatted_adjustment_amount: '€0,00',
    gift_card_amount_cents: 0,
    gift_card_amount_float: 0,
    formatted_gift_card_amount: '€0,00',
    total_tax_amount_cents: 0,
    total_tax_amount_float: 0,
    formatted_total_tax_amount: '€0,00',
    subtotal_tax_amount_cents: 0,
    subtotal_tax_amount_float: 0,
    formatted_subtotal_tax_amount: '€0,00',
    shipping_tax_amount_cents: 0,
    shipping_tax_amount_float: 0,
    formatted_shipping_tax_amount: '€0,00',
    payment_method_tax_amount_cents: 0,
    payment_method_tax_amount_float: 0,
    formatted_payment_method_tax_amount: '€0,00',
    adjustment_tax_amount_cents: 0,
    adjustment_tax_amount_float: 0,
    formatted_adjustment_tax_amount: '€0,00',
    total_amount_cents: 18550,
    total_amount_float: 185.5,
    formatted_total_amount: '€185,50',
    total_taxable_amount_cents: 18550,
    total_taxable_amount_float: 185.5,
    formatted_total_taxable_amount: '€185,50',
    subtotal_taxable_amount_cents: 17350,
    subtotal_taxable_amount_float: 173.5,
    formatted_subtotal_taxable_amount: '€173,50',
    shipping_taxable_amount_cents: 1200,
    shipping_taxable_amount_float: 12,
    formatted_shipping_taxable_amount: '€12,00',
    payment_method_taxable_amount_cents: 0,
    payment_method_taxable_amount_float: 0,
    formatted_payment_method_taxable_amount: '€0,00',
    adjustment_taxable_amount_cents: 0,
    adjustment_taxable_amount_float: 0,
    formatted_adjustment_taxable_amount: '€0,00',
    total_amount_with_taxes_cents: 18550,
    total_amount_with_taxes_float: 185.5,
    formatted_total_amount_with_taxes: '€185,50',
    fees_amount_cents: 0,
    fees_amount_float: 0,
    formatted_fees_amount: '€0,00',
    duty_amount_cents: null,
    duty_amount_float: null,
    formatted_duty_amount: null,
    skus_count: 5,
    line_item_options_count: 0,
    shipments_count: 1,
    tax_calculations_count: 0,
    payment_source_details: { type: 'wire_transfer' },
    token: '8dae3a32b28749d63d8edc0ab155797c',
    cart_url: null,
    return_url: null,
    terms_url: null,
    privacy_url: null,
    checkout_url: null,
    placed_at: null,
    approved_at: null,
    cancelled_at: null,
    payment_updated_at: null,
    fulfillment_updated_at: null,
    refreshed_at: null,
    archived_at: null,
    expires_at: null,
    created_at: '2022-10-03T19:11:30.582Z',
    updated_at: '2022-10-04T03:16:34.302Z',
    reference: null,
    reference_origin: null,
    metadata: {}
  }
}
```

{% endtab %}
{% endtabs %}

#### Place the order

Finally, you can place the order by triggering the `_place` method:

{% tabs %}
{% tab title="CLI Command" %}
The following command places the order:

```shell
cl resources:update orders/wjobhWrZka -a _place=true
```

{% endtab %}

{% tab title="Response" %}
On successful run, the updated order object information is prompted:

```javascript
{
  id: 'wjobhWrZka',
  type: 'orders',
  number: 28117000,
  autorefresh: true,
  status: 'placed',
  payment_status: 'authorized',
  fulfillment_status: 'unfulfilled',
  guest: true,
  editable: false,
  customer_email: 'bolaji@commercelayer.io',
  language_code: 'en',
  currency_code: 'EUR',
  tax_included: true,
  tax_rate: null,
  freight_taxable: null,
  requires_billing_info: false,
  country_code: 'IT',
  shipping_country_code_lock: null,
  coupon_code: null,
  gift_card_code: null,
  gift_card_or_coupon_code: null,
  subtotal_amount_cents: 17350,
  subtotal_amount_float: 173.5,
  formatted_subtotal_amount: '€173,50',
  shipping_amount_cents: 1200,
  shipping_amount_float: 12,
  formatted_shipping_amount: '€12,00',
  payment_method_amount_cents: 0,
  payment_method_amount_float: 0,
  formatted_payment_method_amount: '€0,00',
  discount_amount_cents: 0,
  discount_amount_float: 0,
  formatted_discount_amount: '€0,00',
  adjustment_amount_cents: 0,
  adjustment_amount_float: 0,
  formatted_adjustment_amount: '€0,00',
  gift_card_amount_cents: 0,
  gift_card_amount_float: 0,
  formatted_gift_card_amount: '€0,00',
  total_tax_amount_cents: 0,
  total_tax_amount_float: 0,
  formatted_total_tax_amount: '€0,00',
  subtotal_tax_amount_cents: 0,
  subtotal_tax_amount_float: 0,
  formatted_subtotal_tax_amount: '€0,00',
  shipping_tax_amount_cents: 0,
  shipping_tax_amount_float: 0,
  formatted_shipping_tax_amount: '€0,00',
  payment_method_tax_amount_cents: 0,
  payment_method_tax_amount_float: 0,
  formatted_payment_method_tax_amount: '€0,00',
  adjustment_tax_amount_cents: 0,
  adjustment_tax_amount_float: 0,
  formatted_adjustment_tax_amount: '€0,00',
  total_amount_cents: 18550,
  total_amount_float: 185.5,
  formatted_total_amount: '€185,50',
  total_taxable_amount_cents: 18550,
  total_taxable_amount_float: 185.5,
  formatted_total_taxable_amount: '€185,50',
  subtotal_taxable_amount_cents: 17350,
  subtotal_taxable_amount_float: 173.5,
  formatted_subtotal_taxable_amount: '€173,50',
  shipping_taxable_amount_cents: 1200,
  shipping_taxable_amount_float: 12,
  formatted_shipping_taxable_amount: '€12,00',
  payment_method_taxable_amount_cents: 0,
  payment_method_taxable_amount_float: 0,
  formatted_payment_method_taxable_amount: '€0,00',
  adjustment_taxable_amount_cents: 0,
  adjustment_taxable_amount_float: 0,
  formatted_adjustment_taxable_amount: '€0,00',
  total_amount_with_taxes_cents: 18550,
  total_amount_with_taxes_float: 185.5,
  formatted_total_amount_with_taxes: '€185,50',
  fees_amount_cents: 0,
  fees_amount_float: 0,
  formatted_fees_amount: '€0,00',
  duty_amount_cents: null,
  duty_amount_float: null,
  formatted_duty_amount: null,
  skus_count: 5,
  line_item_options_count: 0,
  shipments_count: 1,
  tax_calculations_count: 0,
  payment_source_details: { type: 'wire_transfer' },
  token: '8dae3a32b28749d63d8edc0ab155797c',
  cart_url: null,
  return_url: null,
  terms_url: null,
  privacy_url: null,
  checkout_url: null,
  placed_at: '2022-10-04T04:13:20.918Z',
  approved_at: null,
  cancelled_at: null,
  payment_updated_at: '2022-10-04T04:13:20.893Z',
  fulfillment_updated_at: null,
  refreshed_at: '2022-10-04T03:45:44.726Z',
  archived_at: null,
  expires_at: null,
  created_at: '2022-10-03T19:11:30.582Z',
  updated_at: '2022-10-04T04:13:20.925Z',
  reference: null,
  reference_origin: null,
  metadata: {}
}
```

{% endtab %}
{% endtabs %}

## Create sales channel API credentials

Follow [these steps](/core/api-credentials#create-a-sales-channel) to create new sales channel API credentials (**client ID** and **base endpoint**) from the dashboard. Remember to save them as we'll use them to [interact with the checkout plugin of the CLI](#generate-a-checkout-url) later.

## Generate a checkout URL

You can create a checkout link using our [hosted checkout](https://github.com/commercelayer/commercelayer-react-checkout) application. With this, you can checkout an order in a web browser. To get started, you need to install the [checkout plugin](https://github.com/commercelayer/commercelayer-cli-plugin-checkout/) using the command below:

```shell
cl plugins:install checkout
```

{% hint style="info" %}
You can use the `cl checkout --help` command to see the list of available commands and what they do.
{% endhint %}

Only a [sales channel](/core/api-credentials#sales-channel) access token can be used to generate a checkout URL. So, use the command below to log with your [previously created](#create-sales-channel-api-credentials) sales channel API credentilas (similar to what you did [before](#log-in-using-the-api-credentials)):

```shell
cl applications:login -o <organizationSlug> -i <clientId> -S <scope> -a <applicationAlias>
```

Where:

* The `-S` flag is required for sales channels and allows you to pass in your [application scope](/core/authentication#authorization-scopes) as a parameter.

If you have already logged in, you can just switch to the sales channel API credentials using the command below:

```shell
cl app:switch -a <applicationAlias>
```

#### Place an order with the order ID

If you have the ID of an order ready to be placed, you can generate a valid checkout URL like so:

{% tabs %}
{% tab title="CLI command" %}
The following command creates a checkout URL associated with an order:

```shell
cl checkout -O <order-id>
```

{% endtab %}

{% tab title="Response" %}
The checkout URL is returned:

```
Checkout URL for order wjobhWrZka:

https://cake-store.checkout.commercelayer.app/wjobhWrZka?accessToken=eyJhbGciOiJIUzUxMiJ9.eyJvcmdhbml6YXRpb24iOnsiaWQiOiJFbnBWT0ZyS3Z5Iiwic2x1ZyI6ImNha2Utc3RvcmUiLCJlbnRlcnByaXNlIjpmYWxzZX0sImFwcGxpY2F0aW9uIjp7ImlkIjoid05iam1pd0JvTiIsImtpbmQiOiJzYWxlc19jaGFubmVsIiwicHVibGljIjp0cnVlfSwidGVzdCI6dHJ1ZSwiZXhwIjoxNjk2MzkxMTMwLCJtYXJrZXQiOnsiaWQiOlsiWWxxeEdoS3JRZyJdLCJwcmljZV9saXN0X2lkIjoid2xacnZDWXJLbCIsInN0b2NrX2xvY2F0aW9uX2lkcyI6WyJ6bkJqeHVsTFZuIiwiWmtZcVh1ZFZkayJdLCJnZW9jb2Rlcl9pZCI6bnVsbCwiYWxsb3dzX2V4dGVybmFsX3ByaWNlcyI6ZmFsc2V9LCJyYW5kIjowLjExNTQ0NjUyOTM2MjgzMn0.Bh-DuqgqgxLHy8QhdcTj8rf2SS3xeu5NECyZSWsJw3ZwTyVqB5U9oSx3tki2vwFbAyxcLLHv-U69nCWqy2FbtA
```

{% endtab %}
{% endtabs %}

#### Checkout one or more SKUs

Alternatively, you can add new items to an order or directly create a new one and then place it, like so:

{% tabs %}
{% tab title="CLI command" %}
The following command creates an order and the related line items, associated with one or more SKUs. It also creates a checkout URL associated with the order:

```shell
cl checkout -S 5PANECAP000000FFFFFFXXXX -S BACKPACKFFFFFF000000XXXX -S BEACHBAG000000FFFFFFXXXX -m QlNQVhWxbg -e bolaji@commercelayer.io
```

{% endtab %}

{% tab title="Response" %}
The created order ID, line items ID, and checkout URL are returned:

```
Created order wnlKhYmZEE
Created line item NMlZtWKbKw for SKU BEACHBAG000000FFFFFFXXXX and associated to order wnlKhYmZEE
Created line item yeYRtdQmQE for SKU 5PANECAP000000FFFFFFXXXX and associated to order wnlKhYmZEE
Created line item vbmetaMdMP for SKU BACKPACKFFFFFF000000XXXX and associated to order wnlKhYmZEE

Checkout URL for order wnlKhYmZEE:

https://cake-store.checkout.commercelayer.app/wnlKhYmZEE?accessToken=eyJhbGciOiJIUzUxMiJ9.eyJvcmdhbml6YXRpb24iOnsiaWQiOiJFbnBWT0ZyS3Z5Iiwic2x1ZyI6ImNha2Utc3RvcmUiLCJlbnRlcnByaXNlIjpmYWxzZX0sImFwcGxpY2F0aW9uIjp7ImlkIjoid05iam1pd0JvTiIsImtpbmQiOiJzYWxlc19jaGFubmVsIiwicHVibGljIjp0cnVlfSwidGVzdCI6dHJ1ZSwiZXhwIjoxNjk2MzkxMTMwLCJtYXJrZXQiOnsiaWQiOlsiWWxxeEdoS3JRZyJdLCJwcmljZV9saXN0X2lkIjoid2xacnZDWXJLbCIsInN0b2NrX2xvY2F0aW9uX2lkcyI6WyJ6bkJqeHVsTFZuIiwiWmtZcVh1ZFZkayJdLCJnZW9jb2Rlcl9pZCI6bnVsbCwiYWxsb3dzX2V4dGVybmFsX3ByaWNlcyI6ZmFsc2V9LCJyYW5kIjowLjExNTQ0NjUyOTM2MjgzMn0.Bh-DuqgqgxLHy8QhdcTj8rf2SS3xeu5NECyZSWsJw3ZwTyVqB5U9oSx3tki2vwFbAyxcLLHv-U69nCWqy2FbtA
```

{% endtab %}
{% endtabs %}

Here’s a breakdown of each of the command options:

* The `checkout` command uses the installed checkout plugin.
* The `-O` flag allows you to pass in an order ID.
* The `-S` flag allows you to pass in an SKU code.
* The `-m` flag allows you to pass in a market ID.
* The `-e` flag allows you to pass in a customer email.
* The `-c` flag allows you to pass in a coupon code.
* The `-B` flag allows you to pass in a bundle code.

## Further resources

Now that your first organization is properly configured and you managed to place your first order, you can take the time to explore the rest of this getting started section, check the [API reference](https://docs.commercelayer.io/metrics-api-reference/), have a look at our recipe-like [how-tos](https://docs.commercelayer.io/how-tos/), and become a pro!

{% hint style="success" icon="chart-line-up" %}
Do you need to extract some kind of data information from your Commerce Layer's organization? We've got you covered. Check our [Metrics API](https://docs.commercelayer.io/metrics/) and see how it can enable you to gather and aggregate useful data that you can leverage to measure the health and performance of your ecommerce business.
{% endhint %}

{% hint style="success" icon="user" %}
If you want to exercise greater control over your organizational structure and user roles and be able to manage provisioning tasks programmatically instead of manually, leverage our [Provisioning API](https://docs.commercelayer.io/provisioning/).
{% endhint %}

{% hint style="success" icon="gear-complex" %}
Would you like to benefit from a DSL that enables you to define promotional rules? If you're an enterprise customer, you can ask to test our [Rules Engine](https://docs.commercelayer.io/rules-engine/) and start setting up almost any kind of promotions to boost your sales, from the simplest to the most complex.
{% endhint %}

For everything else, [join us on Discord](https://discord.gg/commercelayer) and feel free to ask any questions to the team or get involved in the conversation with the rest of our developers' community.


# API specification

Basic info about endpoints, resources, credentials, and environments

Commerce Layer exposes a fast [REST](http://en.wikipedia.org/wiki/Representational_State_Transfer) API that lets you add ecommerce to your favorite tech stack.

Commerce Layer API is 100% compliant with the [JSON API](http://jsonapi.org/format/) specification (v1.0). It supports compound documents, [sparse fieldsets](/core/sparse-fieldsets), resource linking, [filtering](/core/filtering-data), [sorting](/core/sorting-results), [pagination](/core/pagination), and more. The JSON API community has shared some [client libraries](http://jsonapi.org/implementations/#client-libraries) that can help you get started.

{% hint style="warning" %}
All the strings passed to the API must be [UTF-8](https://en.wikipedia.org/wiki/UTF-8) encoded. Date-time parameters must comply with the [ISO 8601](https://www.w3.org/TR/NOTE-datetime) standard (complete date plus hours, minutes, and seconds — expressed in UTC, with `Z` as a special UTC designator). You can change the date visualization on the Dashboard by setting the desired timezone from your account profile.
{% endhint %}

The guide that follows is your reference for all the operations that you can perform on the API resources and contains all the information you need to get a comprehensive overview of how it works.

{% hint style="success" icon="robot" %}
Commerce Layer documentation is [LLM-ready](/#llm-friendly)! To feed the knowledge base into your own LLM, read [this file](https://docs.commercelayer.io/llms.txt).
{% endhint %}

### Authentication

All API requests must be authenticated. To get a valid access token you need to send a `POST` request to the following endpoint:

```http
https://auth.commercelayer.io/oauth/token
```

{% content-ref url="/pages/-LgCGPTjMSTg9sVBpFDk" %}
[Authentication](/core/authentication)
{% endcontent-ref %}

### Base endpoint

Once you have a valid token, all API requests must be made over [HTTPS](http://en.wikipedia.org/wiki/HTTP_Secure) to the following base endpoint:

```http
https://yourdomain.commercelayer.io
```

Where `yourdomain` is the unique subdomain of your organization.

### Core resources

Commerce Layer commerce API features **400+ endpoints**. Check our [API reference](https://docs.commercelayer.io/api-reference/) for the complete and updated list of all the core resources, in detail. For each single resource you will find:

* The **resource** object and its fields, attributes, and relationships.
* The allowed **CRUD** operations you can perform on the related endpoint with basic examples of the request/response format.

### Credentials

Commerce Layer implements the industry-standard [OAuth 2.0](https://oauth.net/2/) protocol to manage clients' authorization. It defines three types of [API credentials](/core/api-credentials): **sales channel**, **integration**, **webapp**. Which one to use depends on your specific need. You can leverage our [how-tos](https://docs.commercelayer.io/how-tos/) to get started with the most popular use cases.

### Environments

For each organization, you can work either in **test mode** (default) or **live mode**.

{% hint style="info" %}
Working in test mode is **free forever**. You can try Commerce Layer in test mode as long as you need to.
{% endhint %}

Test mode also provides you with a development environment after the go-live. All API calls are identical between the two environments. Use test or live API credentials to make the switch.

{% hint style="warning" %}
Switching to live mode means opening a completely **new** (empty) environment where you can get real orders, with different credentials to access. If you want to replicate your test setup in the live environment you can [export](/core/exporting-resources) most of the resources (SKUs, prices, stock, etc.) from your test env and [import](/core/importing-resources) them to the live one. If you import orders, you will be charged for the placed ones, according to the [pricing plan](https://commercelayer.io/pricing) you subscribed to.
{% endhint %}

{% hint style="success" %}
Test and live mode are two different, separate environments. Once enabled live mode, switching from one to another doesn't affect any functionality of the single env (e.g. switching back from live to test **does not switch off** your live environment and doesn't cause any issue to your live website that will continue working as expected).
{% endhint %}

### Open-source projects and developer tools

[JS SDK](https://github.com/commercelayer/commercelayer-sdk), [CLI](https://github.com/commercelayer/commercelayer-cli), and [React components](https://github.com/commercelayer/commercelayer-react-components) are available as open-source projects. More libraries and SDKs for the most popular languages are coming soon. We also provide a tested and constantly updated [OpenAPI schema](https://data.commercelayer.app/schemas/openapi.json) you can leverage to build mock servers, auto-generate code, and implement contract testing.

### Changelog

To stay up-to-date with any changes we make on Commerce Layer APIs, apps, and open-source projects (including versioning, product releases, new features, and general improvements), make sure to check our [changelog](https://docs.commercelayer.io/changelog/).


# API credentials

An overview of Commerce Layer's API credentials types and how generate them

To use Commerce Layer API you need to be [authorized](/core/authentication) in the first place. This means you need to get a valid access token. The permissions you're granted authenticating with that token are determined by the type of API client you used to get it. Three different types are currently available in order to get your credentials: **sales channel**, **integration**, and **webapp**. Which one to use depends on your specific use case.

{% hint style="info" %}
You can fetch the information about your current API credentials (i.e. the one you used to get your access token) by querying the [application](/core-api-reference/application) endpoint of the Core API. You can manage all the CRUD action on all your [API credentials](/provisioning/api-reference/api_credentials) using the Provisioning API. API credentials management is also available via the admin Dashboard — [read this](#generating-api-credentials) to learn how to do it.
{% endhint %}

### Sales channel

**Sales channels** are used to build any customer touchpoint (e.g. your storefront with a fully-functional shopping cart and checkout flow).

Sales channels grant *non-confidential* (public) API credentials. They can authenticate by providing just a **client ID** and their [permissions](/core/roles-and-permissions#sales-channel) are restricted so that they can be safely used client-side and their tokens exposed to the public without any risks. For example, they can access only one order at a time (the one associated with the shopping cart you're about to checkout, identified by a not guessable, unique hashID) and respond with a `401 Unauthorized` error if you try to request a list of orders.

Sales channels require a [market in scope](/core/authentication#putting-a-market-in-scope) when requesting their access tokens. This way all the API call results are automatically filtered based on the specified scope. In particular:

* Only the **SKUs** that are *sellable* in that market are returned (to be sellable in a market an SKU must have a price in the market's price list and at least one stock item in one of the market's stock locations, regardless of its quantity).
* Only the **prices** associated with that market's price list are returned.
* The **stock** availability is calculated by checking only the stock locations associated with that market (e.g. only the stock items associated with that market's stock locations are returned).

{% hint style="info" %}
Using a sales channel is the most straightforward way to build your customer touchpoint. Anyway, if you want to have complete control over the grants brought to the access tokens, you can always use an [integration](#integration). Just make sure not to expose the secret on the client, by building a dedicated *backend for frontend* (BFF), or properly leveraging serverless functions.
{% endhint %}

### Integration

**Integrations** are used to develop backend integrations with any 3rd-party system.

Integrations provide *confidential* API credentials. They need a **client ID** and a **client secret** to authenticate and can have one of two [roles](/core/roles-and-permissions#integration):

* **Read-only** — to perform `GET` requests on any single resource or list of resources.
* **Admin** — to perform any CRUD (create, retrieve, update, or delete) action on any resource.

{% hint style="info" %}
[Enterprise](https://commercelayer.io/pricing) users can define **custom roles** for their integration API credentials, specifying custom permissions on CRUD actions at the single resource level so as to leverage a granular control, tailored to their needs.
{% endhint %}

### Webapp

**Webapps** are used to develop custom web apps or services for your users, extending Commerce Layer backend with any functionality that is not provided out of the box.

Webapps let you execute the OAuth 2.0 [authorization code](/core/authentication/authorization-code) grant flow to get an access token after a user authorizes an app. They don't come with their own [roles and permissions](/core/roles-and-permissions#webapp), since they get the set of permissions of the authenticated user.

## Generating API credentials

The Core API [application](/core-api-reference/application) endpoint is read-only, meaning that by using the API you can only [retrieve](/core-api-reference/application/retrieve) the information about the API credentials within the current scope. The full set of CRUD operations (create, update, and delete) on all your API credentials are available via the [Provisioning API](/provisioning/api-reference/api_credentials) or via the admin Dashboard, as shown in the screenshots below.

Head over to the *API credentials* section by clicking on the related item under the *Developers* dropdown in the nav menu sidebar on the left of your dashboard. The list of your current available API credentials will be displayed. You can access each one individually to update or delete them. To create a new one, click on *+ New* on the top right of the list:

<figure><img src="/files/wHmE2EVe6kg3C5e5iGBB" alt=""><figcaption></figcaption></figure>

The following page is where you can select the kind of API credentials you want to create.

#### Sales channel <a href="#create-a-sales-channel" id="create-a-sales-channel"></a>

To create a sales channel, select the *Sales channel* card, give your new API credentials a meaningful name, and click on the *Create* button:

<figure><img src="/files/aRjwWI68DLfjIYJI0POy" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/KMZfnDR0PQiFf5L47GVS" alt=""><figcaption></figcaption></figure>

On successful creation, you will enter the details page, where you can find and copy to clipboard your API credentials (**client ID**, **base endpoint**, and allowed **scopes**):

<figure><img src="/files/1V5IKP0XdUJgnNTJPnNw" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
To **update** or **delete** your sales channel just click on the three dots `...` button at the top right corner and select the desired action from the dropdown.
{% endhint %}

#### Integration <a href="#create-an-integration" id="create-an-integration"></a>

To create an integration, select the *Integration* card, give your new API credentials a meaningful name, choose its role from the related dropdown, and click on the *Create* button:

<figure><img src="/files/mdnqp9xO3JVJsOstUNW6" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/fJhcdCbd5EPWn6flfTaG" alt=""><figcaption></figcaption></figure>

On successful creation, you will enter the details page, where you can find and copy to clipboard your API credentials (**client ID**, **client secret**, and **base endpoint**):

<figure><img src="/files/ro66nAOQ9zlUTGSUOJ1H" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
To **update** or **delete** your integration just click on the three dots `...` button at the top right corner and select the desired action from the dropdown.
{% endhint %}

#### Webapp <a href="#create-a-webapp" id="create-a-webapp"></a>

To create a webapp, select the *Webapp* card, give your new API credentials a meaningful name, insert the redirect URI (necessary for the [authorization code](/core/authentication/authorization-code) flow), and click on the *Create* button:

<figure><img src="/files/iVw1MViSNFPibR9h4LdE" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/mcugTlN9DHV9tQ7Co4KU" alt=""><figcaption></figcaption></figure>

On successful creation, you will enter the details page, where you can find and copy to clipboard your API credentials (**client ID**, **client secret**, and **base endpoint**):

<figure><img src="/files/96ieNb1RJSpIIpuQ2VP0" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
To **update** or **delete** your webapp just click on the three dots `...` button at the top right corner and select the desired action from the dropdown.
{% endhint %}


# Authentication

How to get your access token, based on OAuth 2.0 grants

All API requests must be authenticated. To get authorized, you must include a valid access token in the **Authorization** header:

```http
Authorization: Bearer your-access-token
```

To get a valid access token you need to send a `POST` request to the following endpoint:

```http
https://auth.commercelayer.io/oauth/token
```

The payload to be sent with the request differs based on the kind of [API credentials](/core/api-credentials) you want to use to authenticate and will be detailed case by case in the following sections.

{% hint style="info" %}
Please note that the authentication endpoint is subject to a [rate limit](/core/rate-limits) of **max 30 reqs / 1 min** both in live and test mode.
{% endhint %}

{% hint style="success" %}
Check our [JS Auth](https://github.com/commercelayer/commercelayer-js-auth), a TypeScript library wrapper that helps you use Commerce Layer API for authentication, providing also some useful helper methods (e.g. [access token decoding](https://github.com/commercelayer/commercelayer-js-auth?tab=readme-ov-file#decode-an-access-token) and [verification](https://github.com/commercelayer/commercelayer-js-auth?tab=readme-ov-file#verify-an-access-token)).
{% endhint %}

### Authorization grant flows

To get an access token, you need to execute an authorization flow by using valid API credentials for the client.

The authorization flow depends on the [grant type](https://oauth.net/2/grant-types/) as described in the table below:

<table><thead><tr><th>Grant type</th><th data-type="checkbox">Sales channel</th><th data-type="checkbox">Integration</th><th data-type="checkbox">Webapp</th></tr></thead><tbody><tr><td><strong>Client credentials</strong></td><td>true</td><td>true</td><td>false</td></tr><tr><td><strong>Password</strong></td><td>true</td><td>false</td><td>false</td></tr><tr><td><strong>Authorization code</strong></td><td>false</td><td>false</td><td>true</td></tr><tr><td><strong>Refresh token</strong></td><td>true</td><td>false</td><td>true</td></tr><tr><td><strong>JWT bearer</strong></td><td>true</td><td>false</td><td>true</td></tr></tbody></table>

{% hint style="warning" %}
As a general rule, *non-confidential* (public) API credentials (e.g. **sales channels**) can authenticate (requesting and revoking access tokens, using refresh tokens) using just a client ID, without providing a client secret and can be safely used client-side. *Confidential* (private) API credentials (e.g. **integrations**, **webapps**) need a client secret to authenticate.
{% endhint %}

### Access token expiry

For security reasons, access tokens expire after a default period of time. Your access token lifetime differs based on the kind of API credentials you're using:

| API client                                                             | Default lifetime |
| ---------------------------------------------------------------------- | ---------------- |
| [Sales channel](/core/authentication/client-credentials#sales-channel) | **4 hours**      |
| [Integration](/core/authentication/client-credentials#integration)     | **2 hours**      |
| [Webapp](/core/authentication/authorization-code#webapp)               | **2 hours**      |

You can specify a custom lifetime for the token at the API credentials level on the admin Dashboard when you create/update each of them or set it via our [Provisioning API](/provisioning/api-reference/api_credentials#access-token-expiry). The token lifetime value must be expressed **in seconds** and fall within a **min** of **2 hours** (**7200 secs**) and a **max** of **15 days** (**1296000 secs**).

A new token is issued **15 mins** (**900 secs**) before the previous token's expiration date. During that overlap time window, both the new and the old token are valid, thus helping you [optimize your auth token caching strategy](https://docs.commercelayer.io/core/spaces/-Lk-ezuDClaMavTqnRi0/pages/JIcXM2kyzlowkdlApU2D#i-keep-being-rate-limited-on-auth-calls.-what-shall-i-do) and avoid asking for a new token every time you make a call.

{% hint style="info" %}
[Refresh tokens](/core/authentication/refresh-token) have a fixed default lifetime of **2 weeks** that cannot be modified.
{% endhint %}

{% hint style="warning" %}
To avoid security issues, be careful not to set too long expiration dates for your access tokens.
{% endhint %}

### Authorization scopes

For each of the above authorization flows you can restrict the scope to a specific [market](#putting-a-market-in-scope), [store](#putting-a-store-in-scope), and/or [stock location](#putting-a-stock-location-in-scope).

The access token scope is a string that can be composed in two ways:

* by **ID** — `{{resource_name}}:id:{{resource_id}}`

  \
  Where `{{resource_name}}` can be one of `market`, `store`, or `stock_location`, and `{{resource_id}}` is the `id` of the resource (e.g. `market:id:xYZkjABcde`, `store:id:bGvCXzYgNB`, `stock_location:id:WLgbSXqyoZ`).\\
* by **code** — `{{resource_name}}:code:{{resource_code}}`

  \
  Where `{{resource_name}}` can be one of `market`, `store`, or `stock_location`, and `{{resource_code}}` is the `code` of the resource (e.g. `market:code:europe`, `store:code:outlet_ny`, `stock_location:code:eu_warehouse`).

{% hint style="info" %}
Defining a market, store, or stock location code and using it for your scope(s) can come in handy to replicate your setup when switching from *Test* to *Live* mode which are two different, separate [environments](/core/api-specification#environments) where corresponding resources would have different IDs.
{% endhint %}

{% hint style="warning" %}
Using authorization scopes with [integration](/core/api-credentials#integration) API credentials works only if associated with a **custom role**. The results of calls performed with integration API credentials associated with *admin* or *read-only* roles are not filtered, even if a scope was specified when requesting the token.
{% endhint %}

#### Putting a market in scope

By including a market scope in the access token request — `market:id:xYZkjABcde` — all the resources (e.g. SKUs, prices, stock items) you fetch are automatically filtered.

<pre class="language-json"><code class="lang-json">{
  "grant_type": "{{authorization_grant}}",
  "client_id": "{{your_client_id}}",
  ...,
<strong>  "scope": "market:id:xYZkjABcde"
</strong>}
</code></pre>

{% hint style="warning" %}
The market in scope must be *active* (i.e. enabled). [Disabled markets](/core-api-reference/markets#disabling-markets) are excluded from any authorization scope recalculation.
{% endhint %}

{% hint style="info" %}
When [fetching a collection of SKUs](/core/fetching-resources#fetching-a-collection-of-skus) with a market in scope only the SKUs that are *sellable* in that market are returned. To be sellable in a market an SKU must have a price in the market's price list and at least one stock item in one of the market's stock locations, **regardless of its quantity**.
{% endhint %}

{% hint style="warning" %}
**Sales channels** require a market in scope when requesting their access tokens to perform the [permitted CRUD actions](/core/roles-and-permissions#sales-channel). If the market in scope is associated with a customer group, it becomes private and can be accessed only by the customers belonging to the group — in that case, to get your token you must use the [password flow](/core/authentication/password).
{% endhint %}

#### Putting a store in scope

By including a store scope in the access token request — `store:id:bGvCXzYgNB` — all the resources (e.g. SKUs, prices) you fetch are automatically filtered by the market the store is associated with, orders are associated with the store in scope, and the returned available payment methods are the store's ones (if any, otherwise the associated market ones). When calculating the stock availability, the associated market stock locations hierarchy is extended by adding the store's stock location (if any) as the one with the highest priority and increasing by 1 the inventory model's stock locations cutoff value.

<pre class="language-json"><code class="lang-json">{
  "grant_type": "{{authorization_grant}}",
  "client_id": "{{your_client_id}}",
  ...,
<strong>  "scope": "store:id:bGvCXzYgNB"
</strong>}
</code></pre>

{% hint style="warning" %}
When putting a store in scope, there's no need to specify the associated market, which is inherited from the store itself. Only **one** store in scope is allowed, if you put multiple store in scope the API responds with a `400 Bad Request` error code.
{% endhint %}

#### Putting a stock location in scope

By including a stock location scope in the access token request — `stock_location:id:WLgbSXqyoZ` — the stock is restricted to the SKUs available in that specific stock location.

<pre class="language-json"><code class="lang-json">{
  "grant_type": "{{authorization_grant}}",
  "client_id": "{{your_client_id}}",
  ...,
<strong>  "scope": "market:id:xYZkjABcde stock_location:id:WLgbSXqyoZ"
</strong>}
</code></pre>

{% hint style="warning" %}
When putting a stock location in scope, adding the associated market in the access token request is **mandatory**. If the market scope is missing or the stock location doesn't belong to the market in scope the API responds with a `400 Bad Request` error code.
{% endhint %}


# Client credentials

How to execute the authorization flow and get your access token

**Sales channels** use the `client_credentials` grant type to get a "guest" access token. **Integrations** use the `client_credentials` grant type to get an access token for themselves.

{% hint style="info" %}
By [including a scope](/core/authentication#authorization-scopes) in the access token request, all the resources that you fetch are automatically filtered.
{% endhint %}

## Getting an access token

To get an access token using the `client_credentials` grant type, send a `POST` request to the `/oauth/token` endpoint, passing the API client credentials in the request body.

### Request

**POST** <https://auth.commercelayer.i&#x6F;**/oauth/token>\*\*

### Arguments

| Body parameter      | Type   | Required | Description                                                                     |
| ------------------- | ------ | -------- | ------------------------------------------------------------------------------- |
| **`grant_type`**    | String | Required | `client_credentials`                                                            |
| **`client_id`**     | String | Required | The client ID (from you API credentials).                                       |
| **`client_secret`** | String | Optional | Your client secret (required for [confidential](#integration) API credentials). |
| **`scope`**         | String | Optional | Your access token scope (market, stock location).                               |

{% hint style="warning" %}
**Sales channels** require a market in `scope` when requesting their access token to perform the [permitted CRUD actions](/core/roles-and-permissions#sales-channel). On the other hand, they don't require the `client_secret` argument when using the `client_credentials` grant type. That lets you use them safely client-side.
{% endhint %}

### Examples

#### Sales channel

{% tabs %}
{% tab title="Request" %}
The following request tries to get an access token for a sales channel, using the `client_credentials` grant type and putting in scope the market identified by the ID "xYZkjABcde":

<pre class="language-sh"><code class="lang-sh">curl -g -X POST \
  'https://auth.commercelayer.io/oauth/token' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
<strong>  "grant_type": "client_credentials",
</strong><strong>  "client_id": "{{your_client_id}}",
</strong><strong>  "scope": "market:id:xYZkjABcde"
</strong>}'
</code></pre>

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the requested access token:

<pre class="language-json"><code class="lang-json">{
<strong>  "access_token": "acC3sSt0K3Nwrt6kic7.abc4bnm5...",
</strong>  "token_type": "bearer",
  "expires_in": 14400,
  "scope": "market:id:xYZkjABcde",
  "created_at": 123456789
}
</code></pre>

{% endtab %}
{% endtabs %}

#### Integration

{% tabs %}
{% tab title="Request" %}
The following request tries to get an access token for an integration, using the `client_credentials` grant type:

<pre class="language-javascript"><code class="lang-javascript">curl -g -X POST \
  'https://auth.commercelayer.io/oauth/token' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
<strong>  "grant_type": "client_credentials",
</strong><strong>  "client_id": "{{your_client_id}}",
</strong><strong>  "client_secret": "{{your_client_secret}}"
</strong>}'
</code></pre>

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the requested access token:

<pre class="language-json"><code class="lang-json">{
<strong>    "access_token": "acC3sSt0K3Nwrt6kic7.abc4bnm5...",
</strong>    "token_type": "bearer",
    "expires_in": 7200,
    "scope": "market:all",
    "created_at": 123456789
}
</code></pre>

{% endtab %}
{% endtabs %}


# Password

How to execute the authorization flow and get your access token

The `password` grant type is used by **sales channels** to exchange customer credentials for an access token (i.e. to get a "logged" access token).

{% hint style="info" %}
By [including a scope](/core/authentication#authorization-scopes) in the access token request, all the resources that you fetch are automatically filtered.
{% endhint %}

## Getting an access token

To get an access token using the `password` grant type, send a `POST` request to the `/oauth/token` endpoint, passing the API client credentials in the request body.

### Request

**POST** <https://auth.commercelayer.i&#x6F;**/oauth/token>\*\*

### Arguments

| Body parameter   | Type   | Required | Description                                       |
| ---------------- | ------ | -------- | ------------------------------------------------- |
| **`grant_type`** | String | Required | `password`                                        |
| **`username`**   | String | Required | The customer's email address.                     |
| **`password`**   | String | Required | The customer's password.                          |
| **`client_id`**  | String | Required | Your client ID (from your API credentials).       |
| **`scope`**      | String | Optional | Your access token scope (market, stock location). |

### Example

#### Sales channel

{% tabs %}
{% tab title="Request" %}
The following request tries to get an access token for a sales channel, using the `password` grant type for a specific user, putting in scope the market identified by the ID "xYZkjABcde":

<pre class="language-sh"><code class="lang-sh">curl -g -X POST \
  'https://auth.commercelayer.io/oauth/token' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
<strong>  "grant_type": "password",
</strong><strong>  "username": "john@example.com",
</strong><strong>  "password": "s3creT",
</strong><strong>  "client_id": "{{your_client_id}}",
</strong><strong>  "scope": "market:id:xYZkjABcde"
</strong>}'
</code></pre>

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the requested access token and owner info, along with a [refresh token](/core/authentication/refresh-token#sales-channel):

<pre class="language-json"><code class="lang-json">{
<strong>    "access_token": "acC3sSt0K3Nwrt6kic7.abc4bnm5...",
</strong>    "token_type": "bearer",
    "expires_in": 14400,
<strong>    "refresh_token": "r3fResHt0k3nvbn7mnr9ert123",
</strong>    "scope": "market:id:xYZkjABcde",
    "created_at": 123456789,
<strong>    "owner_id": "zxcVBnMASd",
</strong><strong>    "owner_type": "customer"
</strong>}
</code></pre>

{% endtab %}
{% endtabs %}


# Authorization code

How to execute the authorization flow and get your access token

The authorization code flow enables 3rd-party applications to access resources on behalf of a user without needing to expose their credentials. This flow helps maintain security by keeping the user's credentials confidential and allowing for granular control over the scope of access granted to 3rd-party applications. Here's a step-by-step breakdown of how the authorization code flow works:

1. **User authorization request** — The client application redirects the user to Commerce Layer authorization server with a [request to authorize the application](#getting-an-authorization-code). This request includes the client ID, the requested scope of access, a redirect URI (where the user will be sent after authorization), and the response type set to `code`.
2. **User authentication and authorization**: The authorization server prompts the user to log in and authenticate themselves (if they're not already logged in). Once authenticated, the user is asked to authorize the 3rd-party application to access the requested resources.
3. **Authorization code response**: If the user grants authorization, the authorization server generates an authorization code and sends it back to the client via the redirect URI specified earlier. This code is a short-lived token that can only be exchanged for an access token by the client with the authorization server.
4. **Authorization code exchange**: Upon receiving the authorization code, the client application makes [a request](#getting-an-access-token) to Commerce Layer's Auth API token endpoint, including the authorization code, client ID, client secret, the redirect URI used earlier, and the same scope used to get the authorization code.&#x20;
5. **Access token response**: The authorization server verifies the authenticity of the authorization code, client credentials, and redirect URI. If everything checks out, it responds with an access token and a refresh token. The access token is a bearer token that grants the 3rd-party application access to the requested resources on behalf of the user.
6. **Resource access**: The client application can now use the access token to make authorized requests to Commerce Layer Core API resources.
7. **Token refresh**: If the access token expires or becomes invalid, the client application can use the [refresh token](/core/authentication/refresh-token#webapp-with-authorization-code-flow) to request a new access token without requiring the user to re-authenticate. This helps in maintaining seamless access to resources.

In summary, the `authorization_code` grant type is used by **webapps** to exchange an authorization code for an access token. As you can see from the detailed steps above, unlike the other grant types, the authorization code flow requires two main connected actions:

* Getting an [authorization code](#getting-an-authorization-code) (steps 1-3)
* Exchanging the authorization code for an [access token](#getting-an-access-token) (steps 4-5)

## Getting an authorization code

To request authorization from the user and get an authorization code, create an authorization request link for the user to click on by adding the necessary query parameters (e.g. client credentials, response type, etc.) to the Commerce Layer dashboard `/oauth/authorize` endpoint.

{% hint style="info" %}
The response type must be `code`.
{% endhint %}

{% hint style="warning" %}
For security reasons, authorization codes expire after **10 minutes**. Their short-lived nature enhances security by limiting their potential for misuse if intercepted.
{% endhint %}

### Request

**GET** <https://dashboard.commercelayer.i&#x6F;**/oauth/authorize>\*\*

### Arguments

| Query parameter     | Type   | Required | Description                                                                 |
| ------------------- | ------ | -------- | --------------------------------------------------------------------------- |
| **`client_id`**     | String | Required | Your client ID (from you API credentials).                                  |
| **`redirect_uri`**  | String | Required | Your redirect URI.                                                          |
| **`scope`**         | String | Optional | Your access token scope (market, stock location).                           |
| **`response_type`** | String | Required | `code`                                                                      |
| **`state`**         | String | Optional | A string that is carried through the whole flow and returned to the client. |

{% hint style="warning" %}
The `state` parameter is an optional value but we strongly recommend adding it to your HTTP request since it is a critical security measure that helps prevent/mitigate certain types of attacks (e.g. CSRF, XSS, etc.) and ensures the integrity of the user's session during the authorization process. When the user is redirected back to your app, whatever value you include as the `state` will also be included in the redirect. This gives your app a chance to persist data between the user being directed to the authorization server and back again, such as using the `state` parameter as a session key.
{% endhint %}

{% hint style="info" %}
It is important to note that what you get is not an access token. The only thing you can do with the authorization code is to [make a request to get an access token](#getting-an-access-token).
{% endhint %}

### Example

#### Webapp

To authenticate any users, ask them to visit the following URL. The request tries to get an authorization code, putting in scope the market identified by the ID "xYZkjABcde" and using "1a2b3c" as the state parameter:

<pre><code>GET https://dashboard.commercelayer.io/oauth/authorize?
<strong>  client_id={{your_client_id}}&#x26;
</strong><strong>  redirect_uri={{your_redirect_uri}}&#x26;
</strong><strong>  scope=market:id:xYZkjABcde&#x26;
</strong><strong>  response_type=code&#x26;
</strong><strong>  state=1a2b3c
</strong></code></pre>

If the client ID exists, the user is prompted to authorize the 3rd party application to access their data:&#x20;

<figure><img src="/files/zTrFWZxsT17FEKo2LwGP" alt=""><figcaption></figcaption></figure>

After the authorization, the browser is redirected to the redirect URI (e.g. `https://yourdomain.com/redirect`) with a `code` parameter in the URL:

```http
https://yourdomain.com/redirect?code=auTHc0d3axy123mnb567&state=1a2b3c
```

## Getting an access token

To get an access token using the `authorization_code` grant type, send a `POST` request to the `/oauth/token` endpoint, passing the API client credentials and the code you got from the [previous step](/core/authentication/authorization-code#getting-an-authorization-code) in the request body.

{% hint style="info" %}
The `scope` must be the same passed as query parameters in [the request](/core/authentication/authorization-code#getting-an-authorization-code) you made to get the authorization code.
{% endhint %}

### Request

**POST** <https://auth.commercelayer.i&#x6F;**/oauth/token>\*\*

### **Arguments**

| Body parameter      | Type   | Required | Description                                                                                                                                      |
| ------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`grant_type`**    | String | Required | `authorization_code`                                                                                                                             |
| **`code`**          | String | Required | The authorization code that [you got](/core/authentication/authorization-code#getting-an-authorization-code) from the redirect URI query string. |
| **`client_id`**     | String | Required | Your client ID (from you API credentials).                                                                                                       |
| **`client_secret`** | String | Required | Your client secret (from you API credentials).                                                                                                   |
| **`redirect_uri`**  | String | Required | Your redirect URI.                                                                                                                               |
| **`scope`**         | String | Optional | Your access token scope (market, stock location).                                                                                                |

### Example

#### Webapp

{% tabs %}
{% tab title="Request" %}
The following request tries to get an access token for a webapp, using the `authorization_code` grant type with the code you got from the [previous step](/core/authentication/authorization-code#getting-an-authorization-code):

<pre class="language-sh"><code class="lang-sh">curl -g -X POST \
  'https://auth.commercelayer.io/oauth/token' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
<strong>  "grant_type": "authorization_code",
</strong><strong>  "code": {{your_authorization_code}},
</strong><strong>  "client_id": {{your_client_id}},
</strong><strong>  "client_secret": {{your_client_secret}},
</strong><strong>  "redirect_uri": "{{your_redirect_uri}}",
</strong><strong>  "scope": "market:id:xYZkjABcde"
</strong>}'
</code></pre>

{% hint style="info" %}
The returned `scope` is the same passed as a query parameter in the [request](#getting-an-authorization-code) you made to get the authorization code. If you didn't specify a scope, the returned scope will be `market:all`.
{% endhint %}
{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the requested access token and owner info, along with a [refresh token](/core/authentication/refresh-token#webapp-with-authorization-code-flow):

<pre class="language-json"><code class="lang-json">{
<strong>    "access_token": "acC3sSt0K3Nwrt6kic7.abc4bnm5...",
</strong>    "token_type": "bearer",
    "expires_in": 7200,
<strong>    "refresh_token": "r3fResHt0k3nvbn7mnr9ert123",
</strong>    "scope": "market:id:xYZkjABcde",
    "created_at": 123456789,
<strong>    "owner_id": "zxcVBnMASd",
</strong><strong>    "owner_type": "user"
</strong>}
</code></pre>

{% endtab %}
{% endtabs %}


# Refresh token

How to execute the authorization flow and get your access token

The `refresh_token` grant type is used by clients to exchange a refresh token for an expired access token.

**Sales channels** can use this grant type to refresh a customer's access token with a "remember me" option. **Webapps** can use it to refresh the access token skipping the [authorization code step](/core/authentication/authorization-code#getting-an-authorization-code).

{% hint style="warning" %}
If a scope  (different from the default `market:all`) was included in the expired access token request, you must specify the same scope when using the refresh token.
{% endhint %}

## Getting an access token

To get an access token using the `refresh_token` grant type, send a `POST` request to the `/oauth/token` endpoint, passing the API client credentials in the request body.

### Request

**POST** <https://auth.commercelayer.i&#x6F;**/oauth/token>\*\*

### Arguments

| Body parameter      | Type   | Required | Description                                                                                                                                                   |
| ------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`grant_type`**    | String | Required | `refresh_token`                                                                                                                                               |
| **`refresh_token`** | String | Required | A valid `refresh_token`.                                                                                                                                      |
| **`client_id`**     | String | Required | Your client ID (from you API credentials).                                                                                                                    |
| **`client_secret`** | String | Optional | Your client secret (required for confidential API credentials — i.e. in case of [authorization code flow](#webapp-application-with-authorization-code-flow)). |
| **`scope`**         | String | Optional | Your access token scope (market, stock location). Required if the expired access token had a scope (must be the same).                                        |

### Examples

#### Sales channel with password flow

{% tabs %}
{% tab title="Request" %}
The following request tries to exchange [a valid refresh token](/core/authentication/password#sales-channel) for an expired access token of a sales channel:

<pre class="language-sh"><code class="lang-sh">curl -g -X POST \
  'https://auth.commercelayer.io/oauth/token' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
<strong>    "grant_type": "refresh_token",
</strong><strong>    "refresh_token": "{{your_refresh_token}}",
</strong><strong>    "client_id": "{{your_client_id}}",
</strong><strong>    "scope": "market:id:xYZkjABcde"
</strong>  }'
</code></pre>

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the requested access token and customer info:

<pre class="language-json"><code class="lang-json">{
<strong>    "access_token": "acC3sSt0K3Nwrt6kic7.abc4bnm5...",
</strong>    "token_type": "bearer",
    "expires_in": 14400,
<strong>    "refresh_token": "r3fResHt0k3ndfg6eft3gbj167",
</strong><strong>    "scope": "market:id:xYZkjABcde",
</strong>    "created_at": 123456789,
    "owner_id": "zxcVBnMASd",
    "owner_type": "customer"
}
</code></pre>

{% endtab %}
{% endtabs %}

#### Webapp with authorization code flow

{% tabs %}
{% tab title="Request" %}
The following request tries to exchange [a valid refresh token](/core/authentication/authorization-code#webapp-1) for an expired access token of a webapp:

<pre class="language-sh"><code class="lang-sh">curl -g -X POST \
  'https://auth.commercelayer.io/oauth/token' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
<strong>  "grant_type": "refresh_token",
</strong><strong>  "refresh_token": "{{your_refresh_token}}",
</strong><strong>  "client_id": "{{your_client_id}}",
</strong><strong>  "client_secret": "{{your_client_secret}}"
</strong>}'
</code></pre>

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the requested access token and customer info:

<pre class="language-javascript"><code class="lang-javascript">{
<strong>    "access_token": "acC3sSt0K3Nwrt6kic7.abc4bnm5...",
</strong>    "token_type": "bearer",
    "expires_in": 7200,
<strong>    "refresh_token": "r3fResHt0k3ndfg6eft3gbj167",
</strong><strong>    "scope": "market:all",
</strong>    "created_at": 123456789,
    "owner_id": "zxcVBnMASd",
    "owner_type": "user"
}
</code></pre>

{% endtab %}
{% endtabs %}


# JWT bearer

How to execute the authorization flow and get your access token

Commerce Layer, through OAuth2, provides the support of token exchange in the *on-behalf-of* (delegation) scenario which allows, for example, to make calls on behalf of a user and get an access token of the requesting user without direct user interaction. **Sales channels** and **webapps** can accomplish it by leveraging the JWT Bearer flow, which allows a client application to obtain an access token using a JSON Web Token (JWT) *assertion*.

{% hint style="info" %}
By [including a scope](/core/authentication#authorization-scopes) in the access token request, all the resources that you fetch are automatically filtered.
{% endhint %}

{% hint style="warning" %}
The JWT bearer flow is available **for enterprise plans only**.
{% endhint %}

At a high level, the JWT bearer token authorization grant follows the steps listed below:

1. **Obtaining a JWT assertion** — The client application [creates a JWT assertion](#creating-the-jwt-assertion), which is a digitally signed JSON object containing information about the client and the user on whose behalf the access token is being requested. This JWT assertion can include information such as the issuer (typically the client), the owner (the user on whose behalf the request is made), expiration time, and any other relevant claims. Custom claims can also be added.
2. **Requesting an access token** — The client [sends a token request](#getting-an-access-token) to the Commerce Layer authorization endpoint, including the JWT assertion as part of the request. This request must include the grant type indicating it's a JWT bearer token request, the assertion itself, and any additional parameters required.
3. **Validating the JWT assertion** — Commerce Layer decodes the JWT assertion without verifying its signature but [ensuring its integrity](#invalid-assertions) (e.g. checking that the assertion is well-formed and not too big, that the user exists and that the client is authorized to request an access token on behalf of the specified user).
4. **Issuing an access token** — If the JWT assertion is valid, Commerce Layer Auth API issues an access token to the client application. This access token represents the authorization granted to the client to access Commerce Layer resources on behalf of the user specified in the JWT assertion.
5. **Using the access token** — The client application can now use the access token to make authorized requests to Commerce Layer resources endpoints on behalf of the user, provided that the token has not expired or been [revoked](/core/authentication/revoking-a-token).

## Creating the JWT assertion

The assertion parameter must contain a single JWT encoded with an algorithm of your choice. Populate the `https://commercelayer.io/claims` object with the keys you need to pass all the desired information, such as:

* `owner` — the customer or user you want to make the calls on behalf of.
* `custom_claim` — any other information (key/value pairs) you want to enrich the token with.

<pre class="language-json"><code class="lang-json">{
<strong>  "https://commercelayer.io/claims": {
</strong><strong>    "owner": {
</strong>      "type": "Customer",
      "id": "zxcVBnMASd"
    },
<strong>    "custom_claim": {
</strong>      "foo": "bar"
    }
  },
  "iat": 1707238036,
  ...
}
</code></pre>

### Invalid assertions

The provided assertion is decoded without verifying its signature. Anyway, the [token request](#getting-an-access-token) will fail if the assertion is malformed or doesn't meet specific requirements. For example, the API will return a `400 Bad request` error:

* If the provided assertion resource owner doesn't exist.
* If the JWT assertion byte size is too big (the maximum allowed size is **4KB**).

## Getting an access token

To get an access token using the `urn:ietf:params:oauth:grant-type:jwt-bearer` grant type, send a `POST` request to the `/oauth/token` endpoint, passing the API client credentials in the request body.

{% hint style="warning" %}
For security reasons, the JWT bearer flow requires a client secret, even for sales channels.&#x20;
{% endhint %}

### Request

**POST** <https://auth.commercelayer.i&#x6F;**/oauth/token>\*\*

### Arguments

| Body parameter      | Type   | Required | Description                                                                           |
| ------------------- | ------ | -------- | ------------------------------------------------------------------------------------- |
| **`grant_type`**    | String | Required | `urn:ietf:params:oauth:grant-type:jwt-bearer`                                         |
| **`client_id`**     | String | Required | Your client ID (from your API credentials).                                           |
| **`client_secret`** | String | Required | Your client secret (from your API credentials).                                       |
| **`scope`**         | String | Optional | Your access token scope (market, stock location).                                     |
| **`assertion`**     | String | Required | A single JSON Web Token ([learn more](#creating-the-jwt-assertion)). Max size is 4KB. |

### Examples

#### Sales channel

{% tabs %}
{% tab title="Request" %}
The following request tries to get an access token for a sales channel API client on behalf of the customer identified by the ID "zxcVBnMASd", using the JWT bearer grant type with the [assertion](#creating-the-jwt-assertion) above:

<pre class="language-sh"><code class="lang-sh">curl -g -X POST \
  'https://auth.commercelayer.io/oauth/token' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
<strong>  "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
</strong><strong>  "client_id": "{{your_client_id}}",
</strong><strong>  "client_secret": "{{your_client_secret}}",
</strong><strong>  "assertion": "{{your_jwt_assertion}}"
</strong>}'
</code></pre>

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the requested access token and owner info, along with a [refresh token](/core/authentication/refresh-token#sales-channel):

<pre class="language-json"><code class="lang-json">{
<strong>    "access_token": "acC3sSt0K3Nwrt6kic7.abc4bnm5...",
</strong>    "token_type": "bearer",
    "expires_in": 7200,
<strong>    "refresh_token": "r3fResHt0k3nvbn7mnr9ert123",
</strong>    "scope": "market:all",
    "created_at": 123456789,
<strong>    "owner_id": "zxcVBnMASd",
</strong><strong>    "owner_type": "customer"
</strong>}
</code></pre>

{% endtab %}
{% endtabs %}

The issued token's payload will have the following structure:

<pre class="language-json"><code class="lang-json">{
  "organization": {
    "id": "mzRmbZFPyO",
    "slug": "your-org-slug",
<strong>    "enterprise": true,
</strong>    "region": "eu-west-1"
  },
  "application": {
    "id": "jpYdqiDvMJ",
    "client_id": "cL13nT1Df7f7619d235e4d94b9ab",
<strong>    "kind": "sales_channel",
</strong>    "public": true,
    "confidential": true
  },
  "custom_claim": {
    "foo": "bar"
  },
<strong>  "owner": {
</strong><strong>    "id": "zxcVBnMASd",
</strong><strong>    "type": "Customer"
</strong><strong>  },
</strong>  "scope": "market:all",
  "exp": 1708098399,
  "test": true,
  "rand": 0.3594449293000671,
  "iat": 1707493599,
  "iss": "https://auth.commercelayer.io"
}
</code></pre>

### JWT single sign-on

Commerce Layer lets you authenticate users in your systems and use SSO with JWT so that a user is automatically verified with an identity provider of your choice (such as Auth0, Okta, or even a custom one) when they sign in. To do that you can leverage the JWT bearer flow with the correct assertion.

{% hint style="warning" %}
The customer must exist (or be created) in Commerce Layer. In order to use a [customer token](/core/authentication/password) to manage registered customers, make sure that you have defined a password for the [customer](/core-api-reference/customers) in Commerce Layer. Otherwise, some customer account functionalities may be unavailable (e.g. payment methods won't be saved in the customer wallet and cannot be reused). For security reasons, we strongly recommend choosing strong/random passwords.
{% endhint %}

{% hint style="info" %}
This feature is available **for enterprise plans only**. Read [this blog post](https://commercelayer.io/blog/single-sign-on-with-commerce-layer-using-next-js-and-auth0) to see an example of how to implement SSO with Commerce Layer, using Auth0 and Next.js.
{% endhint %}

{% embed url="<https://commercelayer.io/blog/single-sign-on-with-commerce-layer-using-next-js-and-auth0>" %}


# Revoking a token

How to revoke any kind of access or refresh token

Any previously generated access tokens ([refresh tokens](#revoking-a-refresh-token) included) can be revoked before their natural [expiration date](/core/authentication#access-token-expiry).

To revoke a token, send a `POST` request to the `/oauth/revoke` endpoint, passing the required parameters in the request body. In addition to the token you need to revoke:

* *non-confidential* (public) API credentials that have a customer or a user in the JWT — e.g. sales channel using the [password](/core/authentication/password) or [JWT bearer](/core/authentication/jwt-bearer) flow — require [the client ID only](#revoking-a-sales-channel-customer-token).
* *confidential* (private) API credentials — e.g. integration, webapps — and *non-confidential* (public) API credentials that don't have a customer or a user in the JWT — e.g. guest sales channels using the [client credentials](/core/authentication/client-credentials) flow — require [also the client secret](#revoking-an-integration-access-token).

### Request

**POST** <https://auth.commercelayer.i&#x6F;**/oauth/revoke>\*\*

### Arguments

| Body parameter      | Type   | Required | Description                                                                                                                                      |
| ------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`client_id`**     | String | Required | Your client ID (from your API credentials).                                                                                                      |
| **`client_secret`** | String | Optional | Your client secret (required for confidential API credentials and non-confidential API credetials without a customer or a user in the JWT only). |
| **`token`**         | String | Required | A valid access or refresh token.                                                                                                                 |

### Example

#### Revoking a sales channel customer token

{% tabs %}
{% tab title="Request" %}
The following request revokes an access token generated for a sales channel public API credential using the `password` grant type, before its natural expiration date:

<pre class="language-sh"><code class="lang-sh">curl -g -X POST \
  'https://auth.commercelayer.io/oauth/revoke' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
<strong>  "client_id": "{{your_client_id}}",
</strong><strong>  "token": "{{your_access_token}}"
</strong>}'
</code></pre>

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning an empty object. If you try to authenticate using the revoked access token, the API will return a `401 Unauthorized` error.
{% endtab %}
{% endtabs %}

#### Revoking an integration access token

{% tabs %}
{% tab title="Request" %}
The following request revokes an access token generated for a private API credential (e.g. integration, webapp, etc.), before its natural expiration date:

<pre class="language-sh"><code class="lang-sh">curl -g -X POST \
  'https://auth.commercelayer.io/oauth/revoke' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
<strong>  "client_id": "{{your_client_id}}",
</strong><strong>  "client_secret": "{{your_client_secret}}",
</strong><strong>  "token": "{{your_access_token}}"
</strong>}'
</code></pre>

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning an empty object. If you try to authenticate using the revoked access token, the API will return a `401 Unauthorized` error.
{% endtab %}
{% endtabs %}

#### Revoking a refresh token

{% tabs %}
{% tab title="Request" %}
The following request revokes a refresh token used to refresh a customer's access token with a "remember me" option (sales channel), before its natural expiration date:

<pre class="language-sh"><code class="lang-sh">curl -g -X POST \
  'https://auth.commercelayer.io/oauth/revoke' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
<strong>  "client_id": "{{your_client_id}}",
</strong><strong>  "token": "{{your_refresh_token}}"
</strong>}'
</code></pre>

{% hint style="info" %}
To revoke a refresh token used to skip the [authorization code step](/core/authentication/authorization-code#getting-an-authorization-code) (webapp), remember to add the webapp client secret to the payload.
{% endhint %}
{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning an empty object.
{% endtab %}
{% endtabs %}


# How to migrate

The simple steps you need to take to make sure your integration is up-to-date with the new Authentication API

{% hint style="danger" %}
We've recently migrated the whole authentication process to our new [Authentication API](/core/authentication). The legacy endpoints, scope syntax, and SSO using a custom org-specific secret key are no longer supported since **November 2024**. If you need to manage any projects or Commerce Layer integrations that still leverage the old way of authenticating, please follow the steps below to update them.
{% endhint %}

To migrate to the new authentication process you just need a couple of tweaks to your current codebase:

1. Change the authentication endpoint from `https://yourdomain.commercelayer.io/oauth` to `https://auth.commercelayer.io/oauth`
2. Stop using the market and/or stock location number (e.g.: `market:1234`) when [including a scope](/core/authentication#authorization-scopes) and start using the new syntax with the ID or the code (e.g. `market:id:xYZkjABcde` or `market:code:europe`).
3. If you're still leveraging a custom org-specific secret key to sign a manually built JWT for SSO, switch to the [JWT bearer](/core/authentication/jwt-bearer) flow with a proper [assertion](/core/authentication/jwt-bearer#creating-the-jwt-assertion).


# Roles and permissions

How to set specific permitted actions for each resource

Commerce Layer supports a granular access control system on a resource level. Each access token gets a specific set of permissions. The client and the [authorization flow](/core/authentication#authorization-flows) determine your permitted actions for each resource.

{% content-ref url="/pages/-LgCGPTjMSTg9sVBpFDk" %}
[Authentication](/core/authentication)
{% endcontent-ref %}

### Sales channel

[Sales channels](/core/api-credentials#sales-channel) support `client_credentials`, `password` and `refresh_token` [grant types](/core/authentication#authorization-grant-flows). Given their limited permissions, they can be safely used in client-side applications.

#### Client credentials

Sales channels that authenticate through `client_credentials` get the following permissions.

{% hint style="danger" %}
For security reasons **sales channels** can read resource lists only for a subset of resources (e.g. SKUs, prices, bundles, etc. — *Show+List* in the table below). Getting a list is not allowed for all the other resources (only *Show* in the table below). For example, a sales channel is authorized to perform a `GET` request to the `/api/orders/xYZkjABcde` but not to the `/api/orders` endpoint.
{% endhint %}

<table><thead><tr><th width="160">Resource</th><th width="85" data-type="checkbox">Create</th><th width="90">Read<select multiple><option value="a3MVF89WVveV" label="Show" color="blue"></option><option value="MDJUWTMhGhy2" label="List" color="blue"></option></select></th><th width="90" data-type="checkbox">Update</th><th width="90" data-type="checkbox">Delete</th><th>Restrictions</th></tr></thead><tbody><tr><td><strong>Addresses</strong></td><td>true</td><td><span data-option="a3MVF89WVveV">Show</span></td><td>true</td><td>true</td><td>Single resource only.</td></tr><tr><td><strong>Application</strong></td><td>false</td><td><span data-option="a3MVF89WVveV">Show</span></td><td>false</td><td>false</td><td>The kind of <a href="/pages/YH8iTTmuUoiFG5ex0bNX">API credentials</a> you're currently using.</td></tr><tr><td><strong>Bundles</strong></td><td>false</td><td><span data-option="MDJUWTMhGhy2">List, </span><span data-option="a3MVF89WVveV">Show</span></td><td>false</td><td>false</td><td>Bundles associated with the market in scope, or (if no market is in scope) with the currency code of the price list in scope.</td></tr><tr><td><strong>Customers</strong></td><td>true</td><td></td><td>false</td><td>false</td><td></td></tr><tr><td><strong>Customer password resets</strong></td><td>false</td><td></td><td>true</td><td>false</td><td></td></tr><tr><td><strong>Customer subscriptions</strong></td><td>true</td><td><span data-option="a3MVF89WVveV">Show</span></td><td>true</td><td>true</td><td>Single resource only.</td></tr><tr><td><strong>Delivery lead times</strong></td><td>false</td><td><span data-option="MDJUWTMhGhy2">List, </span><span data-option="a3MVF89WVveV">Show</span></td><td>false</td><td>false</td><td>Delivery lead times associated with the shipping methods accessible by scope.</td></tr><tr><td><strong>Geocoders</strong></td><td>false</td><td><span data-option="a3MVF89WVveV">Show</span></td><td>false</td><td>false</td><td>Single resource only.</td></tr><tr><td><strong>Gift cards</strong></td><td>true</td><td><span data-option="a3MVF89WVveV">Show</span></td><td>true</td><td>true</td><td>If draft (single resource only).</td></tr><tr><td><strong>Gift card recipients</strong></td><td>true</td><td><span data-option="a3MVF89WVveV">Show</span></td><td>true</td><td>true</td><td>Single resource only.</td></tr><tr><td><strong>In-stock subscriptions</strong></td><td>true</td><td><span data-option="a3MVF89WVveV">Show</span></td><td>true</td><td>true</td><td>In-stock subscriptions associated with the market in scope (single resource only).</td></tr><tr><td><strong>Line items</strong></td><td>true</td><td><span data-option="a3MVF89WVveV">Show</span></td><td>true</td><td>true</td><td>Can be read if belonging to <em>draft</em>, <em>pending</em> or <em>placed</em> orders and updated/deleted if belonging to <em>draft</em> or <em>pending</em> orders (single resource only).</td></tr><tr><td><strong>Line item options</strong></td><td>true</td><td><span data-option="a3MVF89WVveV">Show</span></td><td>true</td><td>true</td><td>Can be read if belonging line items associated with <em>draft</em>, <em>pending</em> or <em>placed</em> orders and updated/deleted if belonging to line items associated with <em>draft</em> or <em>pending</em> orders (single resource only).</td></tr><tr><td><strong>Notifications</strong></td><td>false</td><td><span data-option="MDJUWTMhGhy2">List, </span><span data-option="a3MVF89WVveV">Show</span></td><td>false</td><td>false</td><td></td></tr><tr><td><strong>Orders</strong></td><td>true</td><td><span data-option="a3MVF89WVveV">Show</span></td><td>true</td><td>false</td><td>Can be read if <em>draft</em>, <em>pending</em> or <em>placed</em>, as long as marked as <code>guest</code>. Can be updated if <em>draft</em> or <em>pending</em> (single resource only).</td></tr><tr><td><strong>Organization</strong></td><td>false</td><td><span data-option="a3MVF89WVveV">Show</span></td><td>false</td><td>false</td><td>Your current organization.</td></tr><tr><td><strong>Payment methods</strong></td><td>false</td><td><span data-option="MDJUWTMhGhy2">List, </span><span data-option="a3MVF89WVveV">Show</span></td><td>false</td><td>false</td><td>Enabled payment methods associated with the market in scope, or (if no market is in scope) with the currency code of the price list in scope.</td></tr><tr><td><strong>Payment sources</strong></td><td>true</td><td><span data-option="a3MVF89WVveV">Show</span></td><td>true</td><td>true</td><td>Can be read if belonging to <em>draft</em>, <em>pending</em> or <em>placed</em> orders and updated/deleted if belonging to <em>draft</em> or <em>pending</em> orders (single resource only).</td></tr><tr><td><strong>Prices</strong></td><td>false</td><td><span data-option="MDJUWTMhGhy2">List, </span><span data-option="a3MVF89WVveV">Show</span></td><td>false</td><td>false</td><td>Prices associated with the market price list.</td></tr><tr><td><strong>Price tiers</strong></td><td>false</td><td><span data-option="MDJUWTMhGhy2">List, </span><span data-option="a3MVF89WVveV">Show</span></td><td>false</td><td>false</td><td>Price tiers associated with the prices accessible by scope.</td></tr><tr><td><strong>Promotions</strong></td><td>false</td><td><span data-option="MDJUWTMhGhy2">List, </span><span data-option="a3MVF89WVveV">Show</span></td><td>false</td><td>false</td><td>Active promotions associated with the market in scope, or (if no market is in scope) with the currency code of the price list in scope, plus all promotions that aren't associated with any market and currency code.</td></tr><tr><td><strong>Promotion rules</strong></td><td>false</td><td><span data-option="a3MVF89WVveV">Show</span></td><td>false</td><td>false</td><td>Promotion rules associated with the promotions accessible by scope (single resource only).</td></tr><tr><td><strong>Reserved stocks</strong></td><td>false</td><td><span data-option="MDJUWTMhGhy2">List, </span><span data-option="a3MVF89WVveV">Show</span></td><td>false</td><td>false</td><td>Reserved stocks  belonging to the stock items of the stock locations associated with the market in scope.</td></tr><tr><td><strong>Shipments</strong></td><td>false</td><td><span data-option="a3MVF89WVveV">Show</span></td><td>true</td><td>false</td><td>Can be read if belonging to <em>draft</em>, <em>pending</em> or <em>placed</em> orders and updated if belonging to <em>draft</em> or <em>pending</em> orders (single resource only).</td></tr><tr><td><strong>Stock line items</strong></td><td>false</td><td><span data-option="a3MVF89WVveV">Show</span></td><td>false</td><td>false</td><td>Can be read if belonging to shipments associated with <em>draft</em>, <em>pending</em>, <em>editing</em> or <em>placed</em> orders (single resource only).</td></tr><tr><td><strong>Shipping methods</strong></td><td>false</td><td><span data-option="MDJUWTMhGhy2">List, </span><span data-option="a3MVF89WVveV">Show</span></td><td>false</td><td>false</td><td>Enabled shipping methods associated with the market in scope, or (if no market is in scope) with the currency code of the price list in scope. If stock location is specified, it's matched with the one in scope.</td></tr><tr><td><strong>Shipping method tiers</strong></td><td>false</td><td><span data-option="MDJUWTMhGhy2">List, </span><span data-option="a3MVF89WVveV">Show</span></td><td>false</td><td>false</td><td>Shipping method tiers associated with the shipping methods accessible by scope.</td></tr><tr><td><strong>SKUs</strong></td><td>false</td><td><span data-option="MDJUWTMhGhy2">List, </span><span data-option="a3MVF89WVveV">Show</span></td><td>false</td><td>false</td><td>SKUs with stock items in the market inventory model (unless not tracked), a price in the market price list (unless external prices allowed).</td></tr><tr><td><strong>SKU options</strong></td><td>false</td><td><span data-option="MDJUWTMhGhy2">List, </span><span data-option="a3MVF89WVveV">Show</span></td><td>false</td><td>false</td><td>SKU options associated with the market in scope, or (if no market is in scope) with the currency code of the price list in scope.</td></tr><tr><td><strong>SKU lists</strong></td><td>false</td><td><span data-option="a3MVF89WVveV">Show</span></td><td>false</td><td>false</td><td>Single resource only.</td></tr><tr><td><strong>SKU list items</strong></td><td>false</td><td><span data-option="a3MVF89WVveV">Show</span></td><td>false</td><td>false</td><td>Single resource only.</td></tr><tr><td><strong>Stock items</strong></td><td>false</td><td><span data-option="MDJUWTMhGhy2">List, </span><span data-option="a3MVF89WVveV">Show</span></td><td>false</td><td>false</td><td>SKU items belonging to the stock locations associated with the market in scope.</td></tr><tr><td><strong>Stock transfers</strong></td><td>false</td><td><span data-option="a3MVF89WVveV">Show</span></td><td>false</td><td>false</td><td>Can be read if belonging to shipments associated with <em>draft</em>, <em>pending</em>, <em>editing</em> or <em>placed</em> orders (single resource only).</td></tr><tr><td><strong>Subscription models</strong></td><td>false</td><td><span data-option="MDJUWTMhGhy2">List, </span><span data-option="a3MVF89WVveV">Show</span></td><td>false</td><td>false</td><td><p>Subscription models associated with the</p><p>market in scope.</p></td></tr><tr><td><strong>Tags</strong></td><td>false</td><td><span data-option="a3MVF89WVveV">Show</span></td><td>false</td><td>false</td><td>Allowed for <a href="/spaces/RWJeylueWkzLadK710XZ/pages/X1x7tLPSk6cgyeoV3Aiu#sales-channel-abilities">specific resources </a>only.</td></tr></tbody></table>

#### Password

Sales channels can authenticate a customer through the `password` flow. The access tokens that they get include the sum of the [client credentials permissions](#client-credentials) plus the ones below.

<table><thead><tr><th width="160">Resource</th><th width="90" data-type="checkbox">Create</th><th width="90" data-type="checkbox">Read</th><th width="90" data-type="checkbox">Update</th><th width="90" data-type="checkbox">Delete</th><th>Restrictions</th></tr></thead><tbody><tr><td><strong>Customers</strong></td><td>false</td><td>true</td><td>true</td><td>true</td><td>The customer must be the authenticated resource owner.</td></tr><tr><td><strong>Customer addresses</strong></td><td>true</td><td>true</td><td>true</td><td>true</td><td>The customer must be the authenticated resource owner.</td></tr><tr><td><strong>Customer payment sources</strong></td><td>false</td><td>true</td><td>true</td><td>true</td><td>The customer must be the authenticated resource owner.</td></tr><tr><td><strong>Customer subscriptions</strong></td><td>true</td><td>true</td><td>true</td><td>true</td><td>The customer must be the authenticated resource owner.</td></tr><tr><td><strong>Line items</strong></td><td>true</td><td>true</td><td>true</td><td>true</td><td>The line items must belong to one of the customer's orders.</td></tr><tr><td><strong>Line item options</strong></td><td>true</td><td>true</td><td>true</td><td>true</td><td>The line item options must belong to one of the line items associated with one of the customer's orders.</td></tr><tr><td><strong>Orders</strong></td><td>true</td><td>true</td><td>true</td><td>true</td><td>Can be deleted only if in <code>editing</code> status. The customer must be the authenticated resource owner.</td></tr><tr><td><strong>Order subscriptions</strong></td><td>true</td><td>true</td><td>true</td><td>false</td><td>The subscriptions must be associated with one of the customer's orders.</td></tr><tr><td><strong>Order subscription items</strong></td><td>true</td><td>true</td><td>true</td><td>false</td><td>The subscriptions items must be associated with one of the customer's subscriptions.</td></tr><tr><td><strong>Parcels</strong></td><td>false</td><td>true</td><td>false</td><td>false</td><td>The parcels must belong to one of the customer's orders.</td></tr><tr><td><strong>Parcel line items</strong></td><td>false</td><td>true</td><td>false</td><td>false</td><td>The parcel line items must belong to one of the parcels associated with one of the customer's orders.</td></tr><tr><td><strong>Returns</strong></td><td>true</td><td>true</td><td>true</td><td>false</td><td>Can be created for one of the customer's order and updated if in <em>draft</em> status.</td></tr><tr><td><strong>Return line items</strong></td><td>true</td><td>true</td><td>false</td><td>false</td><td>The return line items must belong to one of the returns associated with one of customer's order.</td></tr><tr><td><strong>Shipments</strong></td><td>false</td><td>true</td><td>true</td><td>false</td><td>The shipments must belong to one of the customer's orders.</td></tr><tr><td><strong>SKU lists</strong></td><td>true</td><td>true</td><td>true</td><td>true</td><td>The customer must be the authenticated resource owner.</td></tr><tr><td><strong>SKU list items</strong></td><td>true</td><td>true</td><td>true</td><td>true</td><td>The customer must be the authenticated owner of the associated SKU list.</td></tr></tbody></table>

{% hint style="warning" %}
Since customer tokens extend sales channels abilities, to get a list of resources belonging to a customer for those resources that [sales channels](#sales-channel) cannot list you need to fetch them [as relationships](/core/fetching-relationships#fetching-a-list-of-related-resources-1-n-relationship) via the `api/customers` endpoint. For example, you can get all the orders belonging to a customer by querying with a customer token the endpoint `api/customers/xYZkjABcde/orders`, where `xYZkjABcde` is the ID of the customer for which the token was issued.
{% endhint %}

#### Refresh token

An access token obtained through a `refresh_token` inherit the same set of permissions as the one that expired.

### Integration

[Integrations](/core/api-credentials#integration) support the `client_credentials` grant type. The access tokens that they get include the set of permissions of their role.

{% hint style="info" %}
With very few exceptions, the [Core resources](https://docs.commercelayer.io/core-api-reference/) not listed in one of the tables above are likely manageable using **integration** API credentials only.
{% endhint %}

### Webapp

[Webapps](/core/api-credentials#webapp) support `authorization_code` and `refresh_token` grant types. They don't bring any grants to the access tokens and get the set of permissions of the authenticated user's role. Access tokens obtained through a `refresh_token` inherit the same set of permissions as the one that expired.


# Fetching resources

How to fetch single resources or collections

You can fetch either single resources or collections by sending `GET` requests to the resource endpoints.

{% hint style="warning" %}
The **Accept** header must be `application/vnd.api+json`.
{% endhint %}

{% content-ref url="/pages/-LgCGPTjMSTg9sVBpFDk" %}
[Authentication](/core/authentication)
{% endcontent-ref %}

### **Examples**

#### **Fetching a single SKU**

{% tabs %}
{% tab title="Request" %}
The following request fetches a single SKU, the one identified by the ID "xYZkjABcde":

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/skus/xYZkjABcde' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' 
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a single resource object:

```json
{
  "data": {
    "id": "xYZkjABcde",
    "type": "skus",
    "links": {...},
    "attributes": {
      "code": "TSHIRTMM000000FFFFFFXLXX",
      "name": "Men's Black T-shirt with White Logo (XL)",
      "description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
      "image_url": "https://img.yourdomain.com/skus/xYZkjABcde.png",
      "tag_names": "Men, Black, XL",
      "pieces_per_pack": 6,
      "weight": 300.0,
      "unit_of_weight": "gr",
      "hs_tariff_number": null,
      "do_not_ship": false,
      "do_not_track": false,
      "inventory": {
        "available": true,
        "quantity": 10,
        "levels": [
          {
            "quantity": 4,
            "delivery_lead_times": [
              {
                "shipping_method": {
                  "name": "Standard Shipping",
                  "reference": null,
                  "price_amount_cents": 700,
                  "free_over_amount_cents": 9900,
                  "formatted_price_amount": "€7,00",
                  "formatted_free_over_amount": "€99,00"
                },
                "min": {
                  "hours": 72,
                  "days": 3
                },
                "max": {
                  "hours": 120,
                  "days": 5
                }
              },
              {
                "shipping_method": {
                  "name": "Express Delivery",
                  "reference": null,
                  "price_amount_cents": 1200,
                  "free_over_amount_cents": null,
                  "formatted_price_amount": "€12,00",
                  "formatted_free_over_amount": null
                },
                "min": {
                  "hours": 48,
                  "days": 2
                },
                "max": {
                  "hours": 72,
                  "days": 3
                }
              }
            ]
          },
          {
            "quantity": 6,
            "delivery_lead_times": [
              {
                "shipping_method": {
                  "name": "Standard Shipping",
                  "reference": null,
                  "price_amount_cents": 700,
                  "free_over_amount_cents": 9900,
                  "formatted_price_amount": "€7,00",
                  "formatted_free_over_amount": "€99,00"
                },
                "min": {
                  "hours": 96,
                  "days": 4
                },
                "max": {
                  "hours": 144,
                  "days": 6
                }
              },
              {
                "shipping_method": {
                  "name": "Express Delivery",
                  "reference": null,
                  "price_amount_cents": 1200,
                  "free_over_amount_cents": null,
                  "formatted_price_amount": "€12,00",
                  "formatted_free_over_amount": null
                },
                "min": {
                  "hours": 72,
                  "days": 3
                },
                "max": {
                  "hours": 96,
                  "days": 4
                }
              }
            ]
          }
        ]
      },
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANYREFEFERNCE",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "shipping_category": {
        "links": {...}
      },
      "prices": {
        "links": {...}
      },
      "stock_items": {
        "links": {...}
      },
      "delivery_lead_times": {
        "links": {...}
      },
      "sku_options": {
        "links": {...}
      }
    },
    "meta": {
      "mode": "test"
    }
  }
}
```

{% endtab %}
{% endtabs %}

#### **Fetching a collection of SKUs**

{% tabs %}
{% tab title="Request" %}
The following request fetches a collection of SKUs:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/skus' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' 
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of the resource objects:

```json
{
  "data": [
    {
      "id": "xYZkjABcde",
      "type": "skus",
      "links": {...},
      "attributes": {
        "code": "TSHIRTMM000000FFFFFFXLXX",
        "name": "Men's Black T-shirt with White Logo (XL)",
        "description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        "image_url": "https://img.yourdomain.com/skus/xYZkjABcde.png",
        "tag_names": "Men, Black, XL",
        "pieces_per_pack": 6,
        "weight": 300.0,
        "unit_of_weight": "gr",
        "hs_tariff_number": null,
        "do_not_ship": false,
        "do_not_track": false,
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": "ANYREFEFERNCE",
        "metadata": {
          "foo": "bar"
        }
      },
      "relationships": {
        "shipping_category": {
          "links": {...}
        },
        "prices": {
          "links": {...}
        },
        "stock_items": {
          "links": {...}
        },
        "delivery_lead_times": {
          "links": {...}
        },
        "sku_options": {
          "links": {...}
        }
      },
      "meta": {
        "mode": "test"
      }
    },
    {
      "other": "... 9 skus (first page)"
    }
  ],
  "meta": {
    "record_count": 140,
    "page_count": 14
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/skus?page[number]=1&page[size]=10",
    "next": "https://yourdomain.commercelayer.io/api/skus?page[number]=2&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/skus?page[number]=14&page[size]=10"
  }
}
```

{% content-ref url="/pages/-LgSlVz3\_Y6DS2SktOCP" %}
[Pagination](/core/pagination)
{% endcontent-ref %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When fetching SKUs [with a market in scope](/core/authentication#putting-a-market-in-scope) only the SKUs that are *sellable* in that market are returned. To be sellable in a market an SKU must have a price in the market's price list and at least one stock item in one of the market's stock locations, **regardless of its quantity**.
{% endhint %}


# Fetching relationships

How to directly fetch related resources

You can fetch either single related resources or collections by sending `GET` requests to the "related" link `/api/<parent_resource>/:id/<related_resource>` (i.e. the parent resource endpoint, specifying the single parent resource ID and the related resource you want to retrieve).

{% hint style="warning" %}
Make sure to use the **relationship** name and *not* the **resource** name (e.g., if you want to retrieve the billing address associated with an order, use `billing_address` and not just `addresses` — [see example](#fetching-a-single-related-resource-1-1-relationship))
{% endhint %}

{% hint style="info" %}
When fetching a list of related resources results **can be sorted** ([see example](/core/sorting-results#sorting-related-resources)) and **filtered** ([see examples](/core/filtering-data#filtering-related-resources)).
{% endhint %}

### Examples

#### Fetching a single related resource (1:1 relationship)

{% tabs %}
{% tab title="Request" %}
The following request fetches the billing address associated with the order identified by the ID "xYZkjABcde":

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/orders/xYZkjABcde/billing_address' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the single related resource object:

```json
{
  "data": {
    "id": "yzXKjYzaCx",
    "type": "addresses",
    "links": {...},
    "attributes": {
      "business": false,
      "first_name": "John",
      "last_name": "Doe",
      "company": null,
      "full_name": "John Doe",
      "line_1": "1234 5th Avenue",
      "line_2": null,
      "city": "New York",
      "zip_code": "10018",
      "state_code": "NY",
      "country_code": "US",
      "phone": "646-1234567",
      "full_address": "1234 5th Avenue, 10018 New York NY (US) 646-1234567",
      "name": "John Doe, 1234 5th Avenue, 10018 New York NY (US) 646-1234567",
      "email": null,
      "notes": null,
      "lat": null,
      "lng": null,
      "is_localized": false,
      "is_geocoded": false,
      "provider_name": null,
      "map_url": null,
      "static_map_url": null,
      "billing_info": null,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "relationships": {
      "geocoder": {
        "links": {...}
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "JxYabZKcAw"
    }
  }
}
```

{% endtab %}
{% endtabs %}

#### Fetching a list of related resources (1:N relationship)

{% tabs %}
{% tab title="Request" %}
The following request fetches the order history of a specific customer, i.e. the list of orders associated with the customer identified by the ID "xYZkjABcde":

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/customers/xYZkjABcde/orders' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of the related resource objects:

```json
{
  "data": [
    {
      "id": "yzXKjYzaCx",
      "type": "orders",
      "links": {...},
      "attributes": {
        "number": 1234,
        "autorefresh": true,
        "status": "pending",
        "payment_status": "unpaid",
        "fulfillment_status": "unfulfilled",
        "guest": false,
        "editable": true,
        "customer_email": "john@example.com",
        "language_code": "en",
        "currency_code": "USD",
        "tax_included": false,
        "tax_rate": null,
        "freight_taxable": null,
        "requires_billing_info": false,
        "country_code": "US",
        "shipping_country_code_lock": null,
        "coupon_code": null,
        "gift_card_code": null,
        "gift_card_or_coupon_code": null,
        "subtotal_amount_cents": 3480,
        "subtotal_amount_float": 34.8,
        "formatted_subtotal_amount": "$34.80",
        "shipping_amount_cents": 700,
        "shipping_amount_float": 7.0,
        "formatted_shipping_amount": "$7.00",
        "payment_method_amount_cents": 0,
        "payment_method_amount_float": 0.0,
        "formatted_payment_method_amount": "$0.00",
        "discount_amount_cents": 0,
        "discount_amount_float": 0.0,
        "formatted_discount_amount": "$0.00",
        "adjustment_amount_cents": 0,
        "adjustment_amount_float": 0.0,
        "formatted_adjustment_amount": "$0.00",
        "gift_card_amount_cents": 0,
        "gift_card_amount_float": 0.0,
        "formatted_gift_card_amount": "$0.00",
        "total_tax_amount_cents": 0,
        "total_tax_amount_float": 0.0,
        "formatted_total_tax_amount": "$0.00",
        "subtotal_tax_amount_cents": 0,
        "subtotal_tax_amount_float": 0.0,
        "formatted_subtotal_tax_amount": "$0.00",
        "shipping_tax_amount_cents": 0,
        "shipping_tax_amount_float": 0.0,
        "formatted_shipping_tax_amount": "$0.00",
        "payment_method_tax_amount_cents": 0,
        "payment_method_tax_amount_float": 0.0,
        "formatted_payment_method_tax_amount": "$0.00",
        "adjustment_tax_amount_cents": 0,
        "adjustment_tax_amount_float": 0.0,
        "formatted_adjustment_tax_amount": "$0.00",
        "total_amount_cents": 4180,
        "total_amount_float": 41.8,
        "formatted_total_amount": "$41.80",
        "total_taxable_amount_cents": 4180,
        "total_taxable_amount_float": 41.8,
        "formatted_total_taxable_amount": "$41.80",
        "subtotal_taxable_amount_cents": 3480,
        "subtotal_taxable_amount_float": 34.8,
        "formatted_subtotal_taxable_amount": "$34.80",
        "shipping_taxable_amount_cents": 700,
        "shipping_taxable_amount_float": 7.0,
        "formatted_shipping_taxable_amount": "$7.00",
        "payment_method_taxable_amount_cents": 0,
        "payment_method_taxable_amount_float": 0.0,
        "formatted_payment_method_taxable_amount": "$0.00",
        "adjustment_taxable_amount_cents": 0,
        "adjustment_taxable_amount_float": 0.0,
        "formatted_adjustment_taxable_amount": "$0.00",
        "total_amount_with_taxes_cents": 4180,
        "total_amount_with_taxes_float": 41.8,
        "formatted_total_amount_with_taxes": "$41.80",
        "fees_amount_cents": 0,
        "fees_amount_float": 0.0,
        "formatted_fees_amount": "$0.00",
        "duty_amount_cents": null,
        "duty_amount_float": null,
        "formatted_duty_amount": null,
        "skus_count": 1,
        "line_item_options_count": 0,
        "shipments_count": 1,
        "payment_source_details": null,
        "token": "y0ur-t0K3n",
        "cart_url": null,
        "return_url": null,
        "terms_url": null,
        "privacy_url": null,
        "checkout_url": "https://your-checkout-url/yzXKjYzaCx",
        "placed_at": null,
        "approved_at": null,
        "cancelled_at": null,
        "payment_updated_at": null,
        "fulfillment_updated_at": null,
        "refreshed_at": null,
        "archived_at": null,
        "expires_at": null,
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": "",
        "reference_origin": null,
        "metadata": {}
      },
      "relationships": {
        "market": {
          "links": {...}
        },
        "customer": {
          "links": {...}
        },
        "shipping_address": {
          "links": {...}
        },
        "billing_address": {
          "links": {...}
        },
        "available_payment_methods": {
          "links": {...}
        },
        "available_customer_payment_sources": {
          "links": {...}
        },
        "payment_method": {
          "links": {...}
        },
        "payment_source": {
          "links": {...}
        },
        "line_items": {
          "links": {...}
        },
        "shipments": {
          "links": {...}
        },
        "transactions": {
          "links": {...}
        },
        "authorizations": {
          "links": {...}
        },
        "captures": {
            "links": {...}
        },
        "voids": {
          "links": {...}
        },
        "refunds": {
          "links": {...}
        },
        "order_subscriptions": {
            "links": {...}
        },
        "order_copies": {
          "links": {...}
        },
        "attachments": {
          "links": {...}
        }
      },
      "meta": {
        "mode": "test",
        "organization_id": "JxYabZKcAw"
      }
    },
    {
      "other": "... 9 orders (first page)"
    }
  ],
  "meta": {
      "record_count": 70,
      "page_count": 7
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/customers/xYZkjABcde/orders?page[number]=1&page[size]=10",
    "next": "https://yourdomain.commercelayer.io/api/customers/xYZkjABcde/orders?page[number]=2&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/customers/xYZkjABcde/orders?page[number]=7&page[size]=10"
  }
}
```

{% content-ref url="/pages/-LgSlVz3\_Y6DS2SktOCP" %}
[Pagination](/core/pagination)
{% endcontent-ref %}
{% endtab %}
{% endtabs %}


# Including associations

How to include a resource and its associations in the same request

When you fetch a resource or a collection, you can include its associations in the same request, using the `include` query parameter.

{% hint style="warning" %}
The value of the `include` parameter must be a comma-separated list of relationship paths ([see example](#fetching-an-sku-and-some-of-its-associations)) — make sure to avoid whitespaces before or after each comma. A relationship path is a dot-separated list of relationship names ([see example](#using-relationship-paths)). For each included resource you'll find in the `relationships` object of the response an additional `data` array containing their type and ID.
{% endhint %}

{% hint style="info" %}
Included resources **cannot be sorted** or **filtered**. Sort rules and filters apply to the parent resource (e.g. `skus` in the examples below) or to related resources ([see examples](/core/filtering-data#filtering-related-resources)).
{% endhint %}

### Examples

#### Fetching an SKU and some of its associations

{% tabs %}
{% tab title="Request" %}
The following request fetches the SKU identified by the ID "xYZkjABcde" and the related prices and stock items:

```sh
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/skus/xYZkjABcde?include=prices,stock_items' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the resource object and the included associations:

<pre class="language-json"><code class="lang-json">{
  "data": {
    "id": "xYZkjABcde",
    "type": "skus",
    "links": { ... },
    "attributes": { ... },
    "relationships": {
      "shipping_category": { ... },
<strong>      "prices": {
</strong>        "links": { .. },
<strong>        "data": [
</strong><strong>          {
</strong><strong>            "type": "prices",
</strong><strong>            "id": "pxEWUBWXLA"
</strong><strong>          }
</strong><strong>        ]
</strong>      },
<strong>      "stock_items": {
</strong>        "links": { ... },
<strong>        "data": [
</strong><strong>          {
</strong><strong>            "type": "stock_items",
</strong><strong>            "id": "jAdEfdlvBK"
</strong><strong>          },
</strong><strong>          {
</strong><strong>            "type": "stock_items",
</strong><strong>            "id": "jpQRfJlrwN"
</strong><strong>          }
</strong><strong>        ]
</strong>      },
      "stock_reservations": { ... },
      "delivery_lead_times": { ... },
      "sku_options": { ... },
      "attachments": { ... },
      "events": { ... },
      "tags": { ... }
    },
    "meta": {
      "mode": "test",
      "organization_id": "EnAvaFOrRe"
    }
  },
  "included": [
    {
<strong>      "id": "pxEWUBWXLA",
</strong><strong>      "type": "prices",
</strong>      "links": { ... },
      "attributes": {
        "currency_code": "USD",
        "sku_code": "TSHIRTMM000000FFFFFFMXXX",
        "amount_cents": 3480,
        "amount_float": 34.8,
        "formatted_amount": "$34.80",
        "compare_at_amount_cents": 4524,
        "compare_at_amount_float": 45.24,
        "formatted_compare_at_amount": "$45.24",
        "created_at": "2019-05-14T10:36:53.987Z",
        "updated_at": "2019-05-14T10:36:53.987Z",
        "reference": null,
        "reference_origin": null,
        "metadata": {}
      },
      "relationships": {
        "price_list": { ... },
        "sku": { ... },
        "price_tiers": { ... },
        "price_volume_tiers": { ... },
        "price_frequency_tiers": { ... },
        "attachments": { ... }
      },
      "meta": {
        "mode": "test",
        "organization_id": "EnAvaFOrRe"
      }
    },
    {
<strong>      "id": "jAdEfdlvBK",
</strong><strong>      "type": "stock_items",
</strong>      "links": { ... },
      "attributes": {
        "sku_code": "TSHIRTMM000000FFFFFFMXXX",
        "quantity": 76,
        "created_at": "2019-05-14T10:36:53.980Z",
        "updated_at": "2019-05-14T10:36:53.980Z",
        "reference": null,
        "reference_origin": null,
        "metadata": {}
      },
      "relationships": {
        "stock_location": { ... },
        "sku": { ... },
        "reserved_stock": { ... },
        "stock_reservations": { ... },
        "attachments": { ... }
      },
      "meta": {
        "mode": "test",
        "organization_id": "EnAvaFOrRe"
      }
    },
    {
<strong>      "id": "jpQRfJlrwN",
</strong><strong>      "type": "stock_items",
</strong>      "links": { ... },
      "attributes": {
        "sku_code": "TSHIRTMM000000FFFFFFMXXX",
        "quantity": 28,
        "created_at": "2019-05-14T10:36:53.993Z",
        "updated_at": "2019-05-14T10:36:53.993Z",
        "reference": null,
        "reference_origin": null,
        "metadata": {}
      },
      "relationships": {
        "stock_location": { ... },
        "sku": { ... },
        "reserved_stock": { ... },
        "stock_reservations": { ... },
        "attachments": { ... }
      },
      "meta": {
        "mode": "test",
        "organization_id": "EnAvaFOrRe"
      }
    }
  ]
}
</code></pre>

{% endtab %}
{% endtabs %}

#### Using relationship paths

{% tabs %}
{% tab title="Request" %}
The following request features the relationship path `stock_items.reserved_stock` as the value of the include parameter, where `stock_items` is a relationship listed under the SKU resource object, and `reserved_stock` is a relationship listed under the stock item resource object:

```bash
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/skus/xYZkjABcde?include=stock_items.reserved_stock' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the resource object and the included associations:

<pre class="language-json"><code class="lang-json">{
  "data": {
    "id": "xYZkjABcde",
    "type": "skus",
    "links": { ... },
    "attributes": { ... },
    "relationships": {
      "shipping_category": { ... },
      "prices": { ... },
<strong>      "stock_items": {
</strong>        "links": { ... },
<strong>        "data": [
</strong><strong>          {
</strong><strong>            "type": "stock_items",
</strong><strong>            "id": "jAdEfdlvBK"
</strong><strong>          },
</strong><strong>          {
</strong><strong>            "type": "stock_items",
</strong><strong>            "id": "jpQRfJlrwN"
</strong><strong>          }
</strong><strong>        ]
</strong>      },
      "stock_reservations": { ... },
      "delivery_lead_times": { ... },
      "sku_options": { ... },
      "attachments": { ... },
      "events": { ... },
      "tags": { ... }
    },
    "meta": {
      "mode": "test",
      "organization_id": "EnAvaFOrRe"
    }
  },
  "included": [
    {
<strong>      "id": "jAdEfdlvBK",
</strong><strong>      "type": "stock_items",
</strong>      "links": { ... },
      "attributes": {
        "sku_code": "TSHIRTMM000000FFFFFFMXXX",
        "quantity": 76,
        "created_at": "2019-05-14T10:36:53.980Z",
        "updated_at": "2019-05-14T10:36:53.980Z",
        "reference": null,
        "reference_origin": null,
        "metadata": {}
      },
      "relationships": {
        "stock_location": { ... },
        "sku": { ... },
<strong>        "reserved_stock": {
</strong>          "links": { ... },
<strong>          "data": null
</strong>        },
        "stock_reservations": { ... },
        "attachments": { ... }
      },
      "meta": {
        "mode": "test",
        "organization_id": "EnAvaFOrRe"
      }
    },
    {
<strong>      "id": "jpQRfJlrwN",
</strong><strong>      "type": "stock_items",
</strong>      "links": { ... },
      "attributes": {
        "sku_code": "TSHIRTMM000000FFFFFFMXXX",
        "quantity": 28,
        "created_at": "2019-05-14T10:36:53.993Z",
        "updated_at": "2019-05-14T10:36:53.993Z",
        "reference": null,
        "reference_origin": null,
        "metadata": {}
      },
      "relationships": {
        "stock_location": { ... },
        "sku": { ... },
<strong>        "reserved_stock": {
</strong>          "links": { ... },
<strong>          "data": {
</strong><strong>            "type": "reserved_stocks",
</strong><strong>            "id": "noJnMSBLXo"
</strong><strong>          }
</strong>        },
        "stock_reservations": { ... },
        "attachments": { ... }
      },
      "meta": {
        "mode": "test",
        "organization_id": "EnAvaFOrRe"
      }
    },
    {
<strong>      "id": "noJnMSBLXo",
</strong><strong>      "type": "reserved_stocks",
</strong>      "links": { ... },
      "attributes": {
<strong>        "quantity": 5,
</strong>        "created_at": "2023-07-17T10:29:13.433Z",
        "updated_at": "2023-07-17T10:29:13.441Z",
        "reference": null,
        "reference_origin": null,
        "metadata": {}
      },
      "relationships": {
        "stock_item": { ... },
        "sku": { ... },
        "stock_reservations": { ... },
      "meta": {
        "mode": "test",
        "organization_id": "EnAvaFOrRe"
      }
    }
  ]
}
</code></pre>

{% endtab %}
{% endtabs %}

{% hint style="info" %}
You can request to include associations also when [creating](/core/creating-resources) or [updating](/core/updating-resources) resources.
{% endhint %}


# Sparse fieldsets

How to request the API to return only specific fields

When you fetch a resource or collection, you can request the API to return only specific fields, using the `fields` query parameter. This reduces the response payload, optimizing the performances. If you want the API to return also specific related resources data, they must be [included](/core/including-associations) and added to the `fields` list as well.

{% hint style="warning" %}
The value of the `fields` parameter must be a comma-separated list that refers to the name(s) of the fields to be returned. Pay attention to avoid whitespaces before or after each comma.
{% endhint %}

### Examples

#### Requesting specific attributes only

{% tabs %}
{% tab title="Request" %}
The following request fetches an SKU code and name:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/skus/xYZkjABcde?fields[skus]=code,name' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the requested fieldset:

```json
{
  "data": {
    "id": "xYZkjABcde",
    "type": "skus",
    "links": {...},
    "attributes": {
        "code": "TSHIRTMM000000FFFFFFXLXX",
        "name": "Men's Black T-shirt with White Logo (XL)"
    },
    "meta": {...}
  }
}
```

{% endtab %}
{% endtabs %}

#### Requesting specific related resources

{% tabs %}
{% tab title="Request" %}
The following request fetches an SKU code, name, and related prices plus the formatted amount and the related price lists of each price:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/skus/xYZkjABcde?fields[skus]=code,name,prices&fields[prices]=formatted_amount,price_list&include=prices.price_list' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the requested fieldset:

```json
{
  "data": {
    "id": "xYZkjABcde",
    "type": "skus",
    "links": {...},
    "attributes": {
      "code": "TSHIRTMM000000FFFFFFXLXX",
      "name": "Men's Black T-shirt with White Logo (XL)"
    },
    "relationships": {
      "prices": {
        "links": {...},
        "data": [
          {
            "type": "prices",
            "id": "ajKQUMdKQp"
          },
          {
            "type": "prices",
            "id": "AKeQUowyYa"
          }
        ]
      }
    },
    "meta": {...}
  },
  "included": [
    {
      "id": "ajKQUMdKQp",
      "type": "prices",
      "links": {...},
      "attributes": {
        "formatted_amount": "€100,00"
      },
      "relationships": {
        "price_list": {
          "links": {...},
          "data": {
            "type": "price_lists",
            "id": "xlqjNCaKLw"
          }
        }
      },
      "meta": {...}
    },
    {
      "id": "AKeQUowyYa",
      "type": "prices",
      "links": {...},
      "attributes": {
        "formatted_amount": "$124.80"
      },
      "relationships": {
        "price_list": {
          "links": {...},
          "data": {
            "type": "price_lists",
            "id": "vLrWRCJWBE"
          }
        }
      },
      "meta": {...}
    },
    {
      "id": "xlqjNCaKLw",
      "type": "price_lists",
      "links": {...},
      "attributes": {
        "name": "EUR Price List",
        "currency_code": "EUR",
        "tax_included": true,
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": null,
        "reference_origin": null,
        "metadata": {}
      },
      "relationships": {
        "prices": {
          "links": {...}
        },
        "attachments": {
          "links": {...}
        }
      },
      "meta": {...}
    },
    {
      "id": "vLrWRCJWBE",
      "type": "price_lists",
      "links": {...},
      "attributes": {
        "name": "USD Price List",
        "currency_code": "USD",
        "tax_included": false,
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": null,
        "reference_origin": null,
        "metadata": {}
      },
      "relationships": {
          "prices": {
              "links": {...}
          },
          "attachments": {
              "links": {...}
          }
      },
      "meta": {...}
    }
  ]
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
You can request sparse fieldsets also when [creating](/core/creating-resources) or [updating](/core/updating-resources) resources.
{% endhint %}


# Sorting results

How to request a specific sort for the results of a collection of resources

When you fetch a collection of resources, you can request a specific sort for the results, using the `sort` query parameter.

{% hint style="warning" %}
The value of the `sort` parameter must be a comma-separated list of fields. Pay attention to avoid whitespaces before or after each comma.
{% endhint %}

{% hint style="info" %}
The sort order for each field is ascending unless prefixed with a `-` (minus) in which case it's descending.
{% endhint %}

### Sortable fields

Not all resource attributes can be used as sorting parameters. You can get the full list of the sortable attributes from the [documentation](https://docs.commercelayer.io/core-api-reference/) of each resource in the "List all" section (e.g. [sortable fields for SKUs](/core-api-reference/skus/list#sortable-fields)).

{% hint style="info" %}
Please note that if you try to sort a collection of resources by a non-sortable attribute the API which will respond with a `400 Bad Request` status code, due to invalid sort criteria.
{% endhint %}

### Examples

#### Sorting the parent resource by one of its attribute

{% tabs %}
{% tab title="Request" %}
The following request fetches a collection of SKUs sorted alphabetically by their code:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/skus?sort=code' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of the resource objects, sorted in the requested order:

```json
{
  "data": [
    {
      "id": "yzXKjYzaCx",
      "type": "skus",
      "links": {...},
      "attributes": {
        "code": "BABYONBU000000E63E7412MX",
        "name": "Baby's Black Onesie Short Sleeve with Pink Logo (12 Months)",
        "description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        "image_url": "https://img.yourdomain.com/skus/yzXKjYzaCx.png",
        "pieces_per_pack": 6,
        "weight": 300.0,
        "unit_of_weight": "gr",
        "hs_tariff_number": null,
        "do_not_ship": false,
        "do_not_track": false,
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": "ANYREFEFERNCE",
        "metadata": {
          "foo": "bar"
        }
      },
      "relationships": {
        "shipping_category": {
          "links": {...}
        },
        "prices": {
          "links": {...}
        },
        "stock_items": {
          "links": {...}
        },
        "stock_reservations": {
          "links": {...}
        },
        "delivery_lead_times": {
          "links": {...}
        },
        "sku_options": {
          "links": {...}
        },
        { ... }
      },
      "meta": {
        "mode": "test",
        "organization_id": "JxYabZKcAw"
      }
    },
    {
      "other": "... 9 skus (first page)"
    }
  ],
  "meta": {
    "record_count": 140,
    "page_count": 14
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/skus?sort=code&page[number]=1&page[size]=10",
    "next": "https://yourdomain.commercelayer.io/api/skus?sort=code&page[number]=2&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/skus?sort=code&page[number]=14&page[size]=10"
  }
}
```

{% content-ref url="/pages/-LgSlVz3\_Y6DS2SktOCP" %}
[Pagination](/core/pagination)
{% endcontent-ref %}
{% endtab %}
{% endtabs %}

#### Sorting the parent resource by one attribute belonging to a related resource

{% tabs %}
{% tab title="Request" %}
The following request fetches a collection of SKUs sorted alphabetically by the name of the associated shipping category:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/skus?sort=shipping_category.name' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of the resource objects, sorted in the requested order:

```json
{
  "data": [
    {
      "id": "WFrbSXqyoZ",
      "type": "skus",
      "links": {...},
      "attributes": {
        "code": "TSHIRTMM000000FFFFFFXLXX",
        "name": "Men's Black T-shirt with White Logo (XL)",
        "description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        "image_url": "https://img.yourdomain.com/skus/WFrbSXqyoZ.png",
        "pieces_per_pack": 3,
        "weight": 350.0,
        "unit_of_weight": "gr",
        "hs_tariff_number": null,
        "do_not_ship": false,
        "do_not_track": false,
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": "ANYREFEFERNCE",
        "metadata": {
          "foo": "bar"
        }
      },
      "relationships": {
        "shipping_category": {
          "links": {...}
        },
        "prices": {
          "links": {...}
        },
        "stock_items": {
          "links": {...}
        },
        "stock_reservations": {
          "links": {...}
        },
        "delivery_lead_times": {
          "links": {...}
        },
        "sku_options": {
          "links": {...}
        },
        { ... }
      },
      "meta": {
        "mode": "test",
        "organization_id": "JxYabZKcAw"
      }
    },
    {
      "other": "... 9 skus (first page)"
    }
  ],
  "meta": {
    "record_count": 140,
    "page_count": 14
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/skus?sort=code&page[number]=1&page[size]=10",
    "next": "https://yourdomain.commercelayer.io/api/skus?sort=code&page[number]=2&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/skus?sort=code&page[number]=14&page[size]=10"
  }
}
```

{% content-ref url="/pages/-LgSlVz3\_Y6DS2SktOCP" %}
[Pagination](/core/pagination)
{% endcontent-ref %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
The relationship must be one of the sortable relationships for the parent resource (in the example above the shipping category is one of the SKU's [sortable](/core-api-reference/skus/list#sortable-fields) relationships), the attribute must be one of the filterable ones for the related resource (in the example above the name is one of the shipping category's [sortable](/core-api-reference/shipping_categories/list#sortable-fields) attributes).
{% endhint %}

#### Sorting related resources

{% tabs %}
{% tab title="Request" %}
The following request fetches the list of orders associated with a certain customer, sorted by their creation date (descending):

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/customers/xYZkjABcde/orders?sort=-created_at' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of the related resource objects, sorted in the requested order:

```json
{
  "data": [
    {
      "id": "kjVLxYzbAc",
      "type": "orders",
      "links": {...},
      "attributes": {
        "number": 1234,
        "autorefresh": true,
        "status": "pending",
        "payment_status": "unpaid",
        "fulfillment_status": "unfulfilled",
        "guest": false,
        "editable": true,
        "customer_email": "john@example.com",
        "language_code": "en",
        "currency_code": "USD",
        "tax_included": false,
        "tax_rate": null,
        "freight_taxable": null,
        "requires_billing_info": false,
        "country_code": "US",
        "shipping_country_code_lock": null,
        "coupon_code": null,
        "gift_card_code": null,
        "gift_card_or_coupon_code": null,
        "subtotal_amount_cents": 3480,
        "subtotal_amount_float": 34.8,
        "formatted_subtotal_amount": "$34.80",
        "shipping_amount_cents": 700,
        "shipping_amount_float": 7.0,
        "formatted_shipping_amount": "$7.00",
        "payment_method_amount_cents": 0,
        "payment_method_amount_float": 0.0,
        "formatted_payment_method_amount": "$0.00",
        "discount_amount_cents": 0,
        "discount_amount_float": 0.0,
        "formatted_discount_amount": "$0.00",
        "adjustment_amount_cents": 0,
        "adjustment_amount_float": 0.0,
        "formatted_adjustment_amount": "$0.00",
        "gift_card_amount_cents": 0,
        "gift_card_amount_float": 0.0,
        "formatted_gift_card_amount": "$0.00",
        "total_tax_amount_cents": 0,
        "total_tax_amount_float": 0.0,
        "formatted_total_tax_amount": "$0.00",
        "subtotal_tax_amount_cents": 0,
        "subtotal_tax_amount_float": 0.0,
        "formatted_subtotal_tax_amount": "$0.00",
        "shipping_tax_amount_cents": 0,
        "shipping_tax_amount_float": 0.0,
        "formatted_shipping_tax_amount": "$0.00",
        "payment_method_tax_amount_cents": 0,
        "payment_method_tax_amount_float": 0.0,
        "formatted_payment_method_tax_amount": "$0.00",
        "adjustment_tax_amount_cents": 0,
        "adjustment_tax_amount_float": 0.0,
        "formatted_adjustment_tax_amount": "$0.00",
        "total_amount_cents": 4180,
        "total_amount_float": 41.8,
        "formatted_total_amount": "$41.80",
        "total_taxable_amount_cents": 4180,
        "total_taxable_amount_float": 41.8,
        "formatted_total_taxable_amount": "$41.80",
        "subtotal_taxable_amount_cents": 3480,
        "subtotal_taxable_amount_float": 34.8,
        "formatted_subtotal_taxable_amount": "$34.80",
        "shipping_taxable_amount_cents": 700,
        "shipping_taxable_amount_float": 7.0,
        "formatted_shipping_taxable_amount": "$7.00",
        "payment_method_taxable_amount_cents": 0,
        "payment_method_taxable_amount_float": 0.0,
        "formatted_payment_method_taxable_amount": "$0.00",
        "adjustment_taxable_amount_cents": 0,
        "adjustment_taxable_amount_float": 0.0,
        "formatted_adjustment_taxable_amount": "$0.00",
        "total_amount_with_taxes_cents": 4180,
        "total_amount_with_taxes_float": 41.8,
        "formatted_total_amount_with_taxes": "$41.80",
        "fees_amount_cents": 0,
        "fees_amount_float": 0.0,
        "formatted_fees_amount": "$0.00",
        "duty_amount_cents": null,
        "duty_amount_float": null,
        "formatted_duty_amount": null,
        "skus_count": 1,
        "line_item_options_count": 0,
        "shipments_count": 1,
        "payment_source_details": null,
        "token": "y0ur-t0K3n",
        "cart_url": null,
        "return_url": null,
        "terms_url": null,
        "privacy_url": null,
        "checkout_url": "https://your-checkout-url/kjVLxYzbAc",
        "placed_at": null,
        "approved_at": null,
        "cancelled_at": null,
        "payment_updated_at": null,
        "fulfillment_updated_at": null,
        "refreshed_at": null,
        "archived_at": null,
        "expires_at": null,
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": "",
        "reference_origin": null,
        "metadata": {}
      },
      "relationships": {
        "market": {
          "links": {...}
        },
        "customer": {
          "links": {...}
        },
        "shipping_address": {
          "links": {...}
        },
        "billing_address": {
          "links": {...}
        },
        "available_payment_methods": {
          "links": {...}
        },
        "available_customer_payment_sources": {
          "links": {...}
        },
        "payment_method": {
          "links": {...}
        },
        "payment_source": {
          "links": {...}
        },
        "line_items": {
          "links": {...}
        },
        "shipments": {
          "links": {...}
        },
        "transactions": {
          "links": {...}
        },
        "authorizations": {
          "links": {...}
        },
        "captures": {
            "links": {...}
        },
        "voids": {
          "links": {...}
        },
        "refunds": {
          "links": {...}
        },
        "order_subscriptions": {
            "links": {...}
        },
        "order_copies": {
          "links": {...}
        },
        "attachments": {
          "links": {...}
        }
      },
      "meta": {
        "mode": "test",
        "organization_id": "JxYabZKcAw"
      }
    },
    {
      "other": "... 9 orders (first page)"
    }
  ],
  "meta": {
      "record_count": 70,
      "page_count": 7
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/customers/xYZkjABcde/orders?sort=-created_at&page[number]=1&page[size]=10",
    "next": "https://yourdomain.commercelayer.io/api/customers/xYZkjABcde/orders?sort=-created_at&page[number]=2&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/customers/xYZkjABcde/orders?sort=-created_at&page[number]=7&page[size]=10"
  }
}
```

{% content-ref url="/pages/-LgSlVz3\_Y6DS2SktOCP" %}
[Pagination](/core/pagination)
{% endcontent-ref %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
You can get the full list of sortable attributes from the [documentation](https://docs.commercelayer.io/core-api-reference/) of each resource.
{% endhint %}


# Pagination

How paginated results work

When you fetch a collection of resources, you get paginated results. The response contains the record and page counts in the `meta` attribute and the URLs of the other pages in the `links` attribute.

```json
{
  "data": [...],
  "meta": {
    "record_count": 140,
    "page_count": 14
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/skus?page[number]=1&page[size]=10",
    "next": "https://yourdomain.commercelayer.io/api/skus?page[number]=2&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/skus?page[number]=14&page[size]=10"
  }
}
```

{% hint style="info" %}
The default page number is **1** (consequently, the link to the `prev` page is missing), and the default page size is **10**. The maximum page size allowed is **25**, but we recommend using a lower value unless strictly necessary. If you need to modify these default settings, use the `page` query parameter in your request.
{% endhint %}

{% hint style="warning" %}
If you need to gather information about large sets of resources for analytics/reporting purposes, please avoid making multiple paginated requests to the related resource endpoint. Use [exports](/core/exporting-resources) instead, which are a best fit for that. Alternatively, you can also perform a [search query](/metrics/getting-started/queries/search) using our [Metrics API](https://docs.commercelayer.io/metrics/) (at the moment limited to [orders](/metrics-api-reference/resources/orders), [carts](/metrics-api-reference/resources/carts), and [returns](/metrics-api-reference/resources/returns)).
{% endhint %}

### Example

{% tabs %}
{% tab title="Request" %}
The following request fetches the SKUs, setting the page number to 3 and the page size to 5:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/skus?page[size]=5&page[number]=3' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the five resource objects listed on the third page (from the 6th object to the 10th), together with the record and page counts and the links to the `first`, `prev`, `next,` and `last` page.

```json
{
  "data": [
    {
      "id": "xYZkjABcde",
      "type": "skus",
      "links": {...},
      "attributes": {...},
      "relationships": {...},
      "meta": {...}
    },
                  {
      "id": "yzkWXfgHQS",
      "type": "skus",
      "links": {...},
      "attributes": {...},
      "relationships": {...},
      "meta": {...}   
    },
    {
      "id": "aBmNkPQRst",
      "type": "skus",
      "links": {...},
      "attributes": {...},
      "relationships": {...},
      "meta": {...}
    },
    {
      "id": "WAspXYhfCV",
      "type": "skus",
      "links": {...},
      "attributes": {...},
      "relationships": {...},
      "meta": {...}
    },
    {
      "id": "QWERtyUpBa",
      "type": "skus",
      "links": {...},
      "attributes": {...},
      "relationships": {...},
      "meta": {...}
    }       
  ],
  "meta": {
    "record_count": 140,
    "page_count": 28
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/skus?page[number]=1&page[size]=5",
    "prev": "https://yourdomain.commercelayer.io/api/skus?page[number]=2&page[size]=5",
    "next": "https://yourdomain.commercelayer.io/api/skus?page[number]=4&page[size]=5",
    "last": "https://yourdomain.commercelayer.io/api/skus?page[number]=28&page[size]=5"
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
The example query parameters above use unencoded `[` and `]` characters simply for readability. In practice, these characters must be percent-encoded, per the requirements in [RFC 3986](http://tools.ietf.org/html/rfc3986#section-3.4).
{% endhint %}

{% hint style="danger" %}
Event stores use a slightly different pagination method based on a cursor instead of the page number (learn more [here](/core-api-reference/event_stores#pagination)).
{% endhint %}


# Filtering data

How to add filters to your requests

When you fetch a collection of resources, you can add filters to further refine the results, using the `filter[q]` query parameter.

{% hint style="info" %}
Filters can be combined according to an "AND" logic to send requests that fetch collections of resources meeting all the criteria within a set of multiple filters ([see example](#combining-filters)).
{% endhint %}

Each single filter query is built like this:

```http
filter[q][{{predicate}}]={{value}}
```

Here, `value` stands for the value that the fetched resources have to match, while the `predicate`parameter has this format:

```
{{attributes}}_{{matcher}}
```

Where `attributes` is a set of one or more attributes and `matcher` represents the condition to be met by the query.

{% hint style="info" %}
Attributes can be combined according to an `OR` logic and can belong to either the fetched resource or to one of its relationships ([see example](#using-filters-that-belong-to-a-resource-relationship)).
{% endhint %}

### List of predicates

You can find here below the complete list of all possible predicates:

| Predicate              | Description                                                                                                             | Example                                                         |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| `*_eq`                 | The attribute is equal to the filter value, not including null values.                                                  | `filter[q][name_eq]=red+handbag`                                |
| `*_eq_or_null`         | The attribute is equal to the filter value, including null values.                                                      | `filter[q][name_eq_or_null]=red+handbag`                        |
| `*_not_eq`             | The attribute is not equal to the filter value, not including null values.                                              | `filter[q][status_not_eq]=prospect`                             |
| `*_not_eq_or_null`     | The attribute is not equal to the filter value, including null values.                                                  | `filter[q][reference_not_eq_or_null]=CRM`                       |
| `*_matches`            | The attribute matches the filter value with "LIKE" operator (works with strings only).                                  | `filter[q][email_matches]=%@gmail.com`                          |
| `*_does_not_match`     | The attribute does not match the filter value with "LIKE" operator (works with strings only).                           | `filter[q][email_does_not_match]=%@hotmail.com`                 |
| `*_matches_any`        | The attribute matches any of the filter values (comma-separated) with "LIKE" operator (works with strings only).        | `filter[q][email_matches_any]=%@gmail.com,%@hotmail.com`        |
| `*_matches_all`        | The attribute matches all of the filter values (comma-separated) with "LIKE" operator (works with strings only).        | `filter[q][name_matches_all]=%Pink%,%Logo%`                     |
| `*_does_not_match_any` | The attribute does not match any of the filter values (comma-separated) with "LIKE" operator (works with strings only). | `filter[q][email_does_not_match_any]=%Pink%,%Logo%`             |
| `*_does_not_match_all` | The attribute matches none of the filter values (comma-separated) with "LIKE" operator (works with strings only).       | `filter[q][email_does_not_match_all]=%@gmail.com,%@hotmail.com` |
| `*_lt`                 | The attribute is less than the filter value.                                                                            | `filter[q][amount_cents_lt]=2000`                               |
| `*_lteq`               | The attribute is less than or equal to the filter value.                                                                | `filter[q][amount_cents_lteq]=2000`                             |
| `*_gt`                 | The attribute is greater than the filter value.                                                                         | `filter[q][created_at_gt]=2019-01-01T01:00:00.000Z`             |
| `*_gteq`               | The attribute is greater than or equal to the filter value.                                                             | `filter[q][updated_at_gteq]=2019-01-02T10:30:00.000Z`           |
| `*_present`            | The attribute is not null and not empty (works with strings only).                                                      | `filter[q][description_present]=false`                          |
| `*_blank`              | The attribute is null or empty (works with strings only).                                                               | `filter[q][description_blank]=true`                             |
| `*_null`               | The attribute is null.                                                                                                  | `filter[q][reference_null]=true`                                |
| `*_not_null`           | The attribute is not null.                                                                                              | `filter[q][reference_not_null]=false`                           |
| `*_in`                 | The attribute matches any of the filter values (comma-separated), not including null values.                            | `filter[q][status_in]=placed,pending`                           |
| \*`_in_or_null`        | The attribute matches any of the filter values (comma-separated), including null values.                                | `filter[q][reference_in_or_null]=CRM,SAP`                       |
| `*_not_in`             | The attribute matches none of the filter values (comma-separated), not including null values.                           | `filter[q][status_not_in]=approved,cancelled`                   |
| `*_not_in_or_null`     | The attribute matches none of the filter values (comma-separated), including null values.                               | `filter[q][reference_not_in_or_null]=CRM,SAP`                   |
| `*_lt_any`             | The attribute is less than any of the filter values (comma-separated).                                                  | `filter[q][amount_cents_lt_any]=1500,700,3400`                  |
| `*_lteq_any`           | The attribute is less than or equal to any of the filter values (comma-separated).                                      | `filter[q][amount_cents_lteq_any]=1500,700,3400`                |
| `*_gt_any`             | The attribute is greater than any of the filter values (comma-separated).                                               | `filter[q][amount_cents_gt_any]=1500,700,3400`                  |
| `*_gteq_any`           | The attribute is greater than or qual to any of the filter values (comma-separated).                                    | `filter[q][amount_cents_gteq_any]=1500,700,3400`                |
| `*_lt_all`             | The attribute is less than all of the filter values (comma-separated).                                                  | `filter[q][amount_cents_lt_all]=1500,700,3400`                  |
| `*_lteq_all`           | The attribute is less than or equal to all of the filter values (comma-separated).                                      | `filter[q][amount_cents_lteq_all]=1500,700,3400`                |
| `*_gt_all`             | The attribute is greater than all of the filter values (comma-separated).                                               | `filter[q][amount_cents_gt_all]=1500,700,3400`                  |
| `*_gteq_all`           | The attribute is greater or equal to all of the filter values (comma-separated).                                        | `filter[q][amount_cents_gteq_all]=1500,700,3400`                |
| `*_not_eq_all`         | The attribute is equal to none of the filter values (comma-separated).                                                  | `filter[q][amount_cents_not_eq_all]=1000,2000,3000`             |
| `*_start`              | The attribute starts with the filter value (comma-separated, works with strings only).                                  | `filter[q][email_start]=patrick`                                |
| `*_not_start`          | The attribute does not start with the filter value (comma-separated, works with strings only).                          | `filter[q][email_not_start]=mary`                               |
| `*_start_any`          | The attribute starts with any of the filter values (comma-separated, works with strings only).                          | `filter[q][email_start_any]=patrick,mary`                       |
| `*_start_all`          | The attribute starts with all of the filter values (comma-separated, works with strings only).                          | `filter[q][email_start_all]=patrick,pat`                        |
| `*_not_start_any`      | The attribute does not start with any of the filter values (comma-separated, works with strings only).                  | `filter[q][email_not_start_any]=patrick,pat`                    |
| `*_not_start_all`      | The attribute starts with none of the filter values (comma-separated, works with strings only).                         | `filter[q][email_not_start_all]=patrick,mary`                   |
| `*_end`                | The attribute ends with the filter value (works with strings only).                                                     | `filter[q][email_end]=.com`                                     |
| `*_not_end`            | The attribute does not end with the filter value (works with strings only).                                             | `filter[q][email_not_end]=.it`                                  |
| `*_end_any`            | The attribute ends with any of the filter values (comma-separated, works with strings only).                            | `filter[q][email_end_any]=.com,.it`                             |
| `*_end_all`            | The attribute ends with all of the filter values (comma-separated, works with strings only).                            | `filter[q][email_end_all]=.com,gmail.com`                       |
| `*_not_end_any`        | The attribute does not end with any of the filter values (comma-separated, works with strings only).                    | `filter[q][email_not_end_any]=.com,gmail.com`                   |
| `*_not_end_all`        | The attribute ends with none of the filter values (comma-separated, works with strings only).                           | `filter[q][email_not_end_all]=.com,.it`                         |
| `*_cont`               | The attribute contains the filter value (works with strings only).                                                      | `filter[q][name_cont]=unisex`                                   |
| `*_not_cont`           | The attribute does not contains the filter value (works with strings only).                                             | `filter[q][name_not_cont]=black`                                |
| `*_cont_any`           | The attribute contains any of the filter values (comma-separated, works with strings only).                             | `filter[q][name_cont_any]=black,white`                          |
| `*_cont_all`           | The attribute contains all of the filter values (comma-separated, works with strings only).                             | `filter[q][name_cont_all]=black,sleeve`                         |
| `*_not_cont_all`       | The attribute contains none of the filter values (comma-separated, works with strings only).                            | `filter[q][sku_code_not_cont_all]=TSHIRT,SXXX`                  |
| `*_jcont`              | The attribute contains a portion of the JSON used as filter value (works with object only).                             | `filter[q][metadata_jcont]={"key": "value"}`                    |
| `*_true`               | The attribute is true.                                                                                                  | `filter[q][tax_included_true]=true`                             |
| `*_false`              | The attribute is false.                                                                                                 | `filter[q][tax_included_false]=true`                            |

{% hint style="warning" %}
In case of comma-separated sets of values (e.g. `*_in`, `*_matches_all`, `*_start_any` etc.), pay attention to avoid whitespaces before or after each comma.
{% endhint %}

{% hint style="warning" %}
Predicates commonly used to filter by string attributes (e.g. `*_cont`, `*_start`, etc.) don't work when trying to filter by ID.
{% endhint %}

### Filterable fields

Not all resource fields can be used as filtering parameters. You can get the full list of the filterable attributes from the [documentation](https://docs.commercelayer.io/core-api-reference/) of each resource in the "List all" section (e.g. [filterable fields for SKUs](/core-api-reference/skus/list#filterable-fields)).

{% hint style="warning" %}
Please note that if you try to filter a collection of resources by a non-filterable field you don't get any error from the API which will respond with a `200 OK` status code, returning the full **unfiltered** list.
{% endhint %}

### Examples

#### Combining filters

{% tabs %}
{% tab title="Request" %}
The following request fetches a collection of SKUs that have been created within a specific time range:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/skus?filter[q][created_at_gt]=2018-01-01&filter[q][created_at_lt]=2018-01-31' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of the resource objects that match the filter query:

```json
{
  "data": [
    {
      "id": "xYZkjABcde",
      "type": "skus",
      "links": {...},
      "attributes": {
        "code": "TSHIRTMM000000FFFFFFXLXX",
        "name": "Men's Black T-shirt with White Logo (XL)",
        "description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        "image_url": "https://img.yourdomain.com/skus/xYZkjABcde.png",
        "tag_names": "Men, Black, XL",
        "pieces_per_pack": 6,
        "weight": 300.0,
        "unit_of_weight": "gr",
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": "ANYREFEFERNCE",
        "metadata": {
          "foo": "bar"
        }
      },
      "relationships": {
        "shipping_category": {
          "links": {...}
        },
        "prices": {
          "links": {...}
        },
        "stock_items": {
          "links": {...}
        },
        "delivery_lead_times": {
          "links": {...}
        },
        "sku_options": {
          "links": {...}
        }
      },
      "meta": {
        "mode": "test"
      }
    },
    {
      "other": "... 9 skus (first page)"
    }
  ],
  "meta": {
    "record_count": 50,
    "page_count": 5
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/skus?filter[q][created_at_gt]=2018-01-01&filter[q][created_at_lt]=2018-01-31&page[number]=1&page[size]=10",
    "next": "https://yourdomain.commercelayer.io/api/skus?filter[q][created_at_gt]=2018-01-01&filter[q][created_at_lt]=2018-01-31&page[number]=2&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/skus?filter[q][created_at_gt]=2018-01-01&filter[q][created_at_lt]=2018-01-31&page[number]=5&page[size]=10"
  }
}
```

{% content-ref url="/pages/-LgSlVz3\_Y6DS2SktOCP" %}
[Pagination](/core/pagination)
{% endcontent-ref %}
{% endtab %}
{% endtabs %}

#### Combining filters and attributes

{% tabs %}
{% tab title="Request" %}
The following request fetches a collection of orders that have been created or updated after a specific date and that haven't been paid yet:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/orders?filter[q][created_at_or_updated_at_gt]=2018-01-01&filter[q][payment_status_eq]=unpaid' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of the resource objects that match the filter query:

```json
{
  "data": [
    {
      "id": "xYZkjABcde",
      "type": "orders",
      "links": {...},
      "attributes": {
        "status": "pending",
        "payment_status": "unpaid",
        "fulfillment_status": "unfulfilled",
        "guest": true,
        "editable": true,
        "placeable": false,
        "customer_email": "john@example.com",
        "language_code": "en",
        "currency_code": "EUR",
        "tax_included": true,
        "tax_rate": null,
        "freight_taxable": null,
        "country_code": null,
        "shipping_country_code_lock": null,
        "coupon_code": null,
        "subtotal_amount_cents": 4400,
        "subtotal_amount_float": 44.0,
        "formatted_subtotal_amount": "€44,00",
        "shipping_amount_cents": 0,
        "shipping_amount_float": 0,
        "formatted_shipping_amount": "€0,00",
        "payment_method_amount_cents": 0,
        "payment_method_amount_float": 0,
        "formatted_payment_method_amount": "€0,00",
        "discount_amount_cents": 0,
        "discount_amount_float": 0,
        "formatted_discount_amount": "€0,00",
        "total_tax_amount_cents": 0,
        "total_tax_amount_float": 0,
        "formatted_total_tax_amount": "€0,00",
        "subtotal_tax_amount_cents": 0,
        "subtotal_tax_amount_float": 0,
        "formatted_subtotal_tax_amount": "€0,00",
        "shipping_tax_amount_cents": 0,
        "shipping_tax_amount_float": 0,
        "formatted_shipping_tax_amount": "€0,00",
        "payment_method_tax_amount_cents": 0,
        "payment_method_tax_amount_float": 0,
        "formatted_payment_method_tax_amount": "€0,00",
        "discount_tax_amount_cents": 0,
        "discount_tax_amount_float": 0,
        "formatted_discount_tax_amount": "€0,00",
        "total_amount_cents": 4400,
        "total_amount_float": 44.0,
        "formatted_total_amount": "€44,00",
        "total_taxable_amount_cents": 4400,
        "total_taxable_amount_float": 44.0,
        "formatted_total_taxable_amount": "€44,00",
        "subtotal_taxable_amount_cents": 4400,
        "subtotal_taxable_amount_float": 44.0,
        "formatted_subtotal_taxable_amount": "€44,00",
        "shipping_taxable_amount_cents": 0,
        "shipping_taxable_amount_float": 0,
        "formatted_shipping_taxable_amount": "€0,00",
        "payment_method_taxable_amount_cents": 0,
        "payment_method_taxable_amount_float": 0,
        "formatted_payment_method_taxable_amount": "€0,00",
        "discount_taxable_amount_cents": 0,
        "discount_taxable_amount_float": 0,
        "formatted_discount_taxable_amount": "€0,00",
        "total_amount_with_taxes_cents": 4400,
        "total_amount_with_taxes_float": 44.0,
        "formatted_total_amount_with_taxes": "€44,00",
        "fees_amount_cents": 0,
        "fees_amount_float": 0,
        "formatted_fees_amount": "€0,00",
        "skus_count": 2,
        "line_item_options_count": 0,
        "shipments_count": 0,
        "payment_source_details": null,
        "token": "order-token",
        "cart_url": null,
        "return_url": null,
        "terms_url": null,
        "privacy_url": null,
        "checkout_url": "https://yourdomain.commercelayer.io/checkout/order-token",
        "placed_at": null,
        "approved_at": null,
        "cancelled_at": null,
        "payment_updated_at": null,
        "fulfillment_updated_at": null,
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": null,
        "metadata": {}
      },
      "relationships": {
        "market": {
          "links": {...}
        },
        "customer": {
          "links": {...}
        },
        "shipping_address": {
          "links": {...}
        },
        "billing_address": {
          "links": {...}
        },
        "available_payment_methods": {
          "links": {...}
        },
        "payment_method": {
          "links": {...}
        },
        "payment_source": {
          "links": {...}
        },
        "line_items": {
          "links": {...}
        },
        "shipments": {
          "links": {...}
        }
      },
      "meta": {
        "mode": "test"
      }
    },
    {
      "other": "... 9 orders (first page)"
    }
  ],
  "meta": {
      "record_count": 10,
      "page_count": 1
  },
  "links": {
      "first": "https://yourdomain.commercelayer.io/api/orders?filter[q][created_at_or_updated_at_gt]=2018-01-01&filter[q][payment_status_eq]=unpaid&page[number]=1&page[size]=10",
      "last": "https://yourdomain.commercelayer.io/api/orders?filter[q][created_at_or_updated_at_gt]=2018-01-01&filter[q][payment_status_eq]=unpaid&page[number]=1&page[size]=10"
  }
}
```

{% content-ref url="/pages/-LgSlVz3\_Y6DS2SktOCP" %}
[Pagination](/core/pagination)
{% endcontent-ref %}
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
When combining attribute make sure not to mix types (e.g. string and integer).
{% endhint %}

#### Using filters that belong to a resource relationship

{% tabs %}
{% tab title="Request" %}
The following request fetches a collection of SKUs whose name, code, or shipping category name starts with the string "TSHIRT" (as mentioned above, the attribute`shipping_category_name` here belongs to a relationship and filters the list of SKUs by the name of the associated shipping category):

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/skus?filter[q][name_or_code_or_shipping_category_name_start]=TSHIRT' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of the resource objects that match the filter query:

```json
{
  "data": [
    {
      "id": "xYZkjABcde",
      "type": "skus",
      "links": {...},
      "attributes": {
        "code": "TSHIRTMM000000FFFFFFXLXX",
        "name": "Men's Black T-shirt with White Logo (XL)",
        "description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        "image_url": "https://img.yourdomain.com/skus/xYZkjABcde.png",
        "tag_names": "Men, Black, XL",
        "pieces_per_pack": 6,
        "weight": 300.0,
        "unit_of_weight": "gr",
        "hs_tariff_number": null,
        "do_not_ship": false,
        "do_not_track": false,
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": "ANYREFEFERNCE",
        "metadata": {
          "foo": "bar"
        }
      },
      "relationships": {
        "shipping_category": {
          "links": {...}
        },
        "prices": {
          "links": {...}
        },
        "stock_items": {
          "links": {...}
        },
        "delivery_lead_times": {
          "links": {...}
        },
        "sku_options": {
          "links": {...}
        }
      },
      "meta": {
        "mode": "test"
      }
    },
    {
      "other": "... 9 skus (first page)"
    }
  ],
  "meta": {
    "record_count": 20,
    "page_count": 2
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/skus?filter[q][name_or_code_or_shipping_category_name_start]=TSHIRT&page[number]=1&page[size]=10",
    "next": "https://yourdomain.commercelayer.io/api/skus?filter[q][name_or_code_or_shipping_category_name_start]=TSHIRT&page[number]=2&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/skus?filter[q][name_or_code_or_shipping_category_name_start]=TSHIRT&page[number]=2&page[size]=10"
  }
}
```

{% content-ref url="/pages/-LgSlVz3\_Y6DS2SktOCP" %}
[Pagination](/core/pagination)
{% endcontent-ref %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
The relationship must be one of the filterable relationships for the parent resource (in the example above the shipping category is one of the SKU's [filterable](/core-api-reference/skus/list#filterable-fields) relationships), the attribute must be one of the filterable ones for the related resource (in the example above the name is one of the shipping category's [filterable](/core-api-reference/shipping_categories/list#filterable-fields) attributes).
{% endhint %}

{% hint style="warning" %}
`*_blank` and `*_present` predicates don't work when filtering on related resources fields (e.g. you cannot check the existence of a relationship using`/api/customers?filter[q][customer_group_id_present]=true`). You can use `*_null` and `*_not_null` instead.
{% endhint %}

#### Filtering related resources

{% tabs %}
{% tab title="Request" %}
The following request fetches the list of orders placed by a certain customer after a specific date:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/customers/xYZkjABcde/orders?filter[q][created_at_gt]=2017-12-12&filter[q][status_eq]=placed' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of the related resource objects that match the filter query:

```json
{
  "data": [
    {
      "id": "yzXKjYzaCx",
      "type": "orders",
      "links": {...},
      "attributes": {
        "number": 1234,
        "autorefresh": true,
        "status": "pending",
        "payment_status": "unpaid",
        "fulfillment_status": "unfulfilled",
        "guest": false,
        "editable": true,
        "customer_email": "john@example.com",
        "language_code": "en",
        "currency_code": "USD",
        "tax_included": false,
        "tax_rate": null,
        "freight_taxable": null,
        "requires_billing_info": false,
        "country_code": "US",
        "shipping_country_code_lock": null,
        "coupon_code": null,
        "gift_card_code": null,
        "gift_card_or_coupon_code": null,
        "subtotal_amount_cents": 3480,
        "subtotal_amount_float": 34.8,
        "formatted_subtotal_amount": "$34.80",
        "shipping_amount_cents": 700,
        "shipping_amount_float": 7.0,
        "formatted_shipping_amount": "$7.00",
        "payment_method_amount_cents": 0,
        "payment_method_amount_float": 0.0,
        "formatted_payment_method_amount": "$0.00",
        "discount_amount_cents": 0,
        "discount_amount_float": 0.0,
        "formatted_discount_amount": "$0.00",
        "adjustment_amount_cents": 0,
        "adjustment_amount_float": 0.0,
        "formatted_adjustment_amount": "$0.00",
        "gift_card_amount_cents": 0,
        "gift_card_amount_float": 0.0,
        "formatted_gift_card_amount": "$0.00",
        "total_tax_amount_cents": 0,
        "total_tax_amount_float": 0.0,
        "formatted_total_tax_amount": "$0.00",
        "subtotal_tax_amount_cents": 0,
        "subtotal_tax_amount_float": 0.0,
        "formatted_subtotal_tax_amount": "$0.00",
        "shipping_tax_amount_cents": 0,
        "shipping_tax_amount_float": 0.0,
        "formatted_shipping_tax_amount": "$0.00",
        "payment_method_tax_amount_cents": 0,
        "payment_method_tax_amount_float": 0.0,
        "formatted_payment_method_tax_amount": "$0.00",
        "adjustment_tax_amount_cents": 0,
        "adjustment_tax_amount_float": 0.0,
        "formatted_adjustment_tax_amount": "$0.00",
        "total_amount_cents": 4180,
        "total_amount_float": 41.8,
        "formatted_total_amount": "$41.80",
        "total_taxable_amount_cents": 4180,
        "total_taxable_amount_float": 41.8,
        "formatted_total_taxable_amount": "$41.80",
        "subtotal_taxable_amount_cents": 3480,
        "subtotal_taxable_amount_float": 34.8,
        "formatted_subtotal_taxable_amount": "$34.80",
        "shipping_taxable_amount_cents": 700,
        "shipping_taxable_amount_float": 7.0,
        "formatted_shipping_taxable_amount": "$7.00",
        "payment_method_taxable_amount_cents": 0,
        "payment_method_taxable_amount_float": 0.0,
        "formatted_payment_method_taxable_amount": "$0.00",
        "adjustment_taxable_amount_cents": 0,
        "adjustment_taxable_amount_float": 0.0,
        "formatted_adjustment_taxable_amount": "$0.00",
        "total_amount_with_taxes_cents": 4180,
        "total_amount_with_taxes_float": 41.8,
        "formatted_total_amount_with_taxes": "$41.80",
        "fees_amount_cents": 0,
        "fees_amount_float": 0.0,
        "formatted_fees_amount": "$0.00",
        "duty_amount_cents": null,
        "duty_amount_float": null,
        "formatted_duty_amount": null,
        "skus_count": 1,
        "line_item_options_count": 0,
        "shipments_count": 1,
        "payment_source_details": null,
        "token": "y0ur-t0K3n",
        "cart_url": null,
        "return_url": null,
        "terms_url": null,
        "privacy_url": null,
        "checkout_url": "https://your-checkout-url/PGWrhEEaYP",
        "placed_at": null,
        "approved_at": null,
        "cancelled_at": null,
        "payment_updated_at": null,
        "fulfillment_updated_at": null,
        "refreshed_at": null,
        "archived_at": null,
        "expires_at": null,
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": "",
        "reference_origin": null,
        "metadata": {}
      },
      "relationships": {
        "market": {
          "links": {...}
        },
        "customer": {
          "links": {...}
        },
        "shipping_address": {
          "links": {...}
        },
        "billing_address": {
          "links": {...}
        },
        "available_payment_methods": {
          "links": {...}
        },
        "available_customer_payment_sources": {
          "links": {...}
        },
        "payment_method": {
          "links": {...}
        },
        "payment_source": {
          "links": {...}
        },
        "line_items": {
          "links": {...}
        },
        "shipments": {
          "links": {...}
        },
        "transactions": {
          "links": {...}
        },
        "authorizations": {
          "links": {...}
        },
        "captures": {
            "links": {...}
        },
        "voids": {
          "links": {...}
        },
        "refunds": {
          "links": {...}
        },
        "order_subscriptions": {
            "links": {...}
        },
        "order_copies": {
          "links": {...}
        },
        "attachments": {
          "links": {...}
        }
      },
      "meta": {
        "mode": "test",
        "organization_id": "JxYabZKcAw"
      }
    },
    {
      "other": "... 9 orders (first page)"
    }
  ],
  "meta": {
      "record_count": 10,
      "page_count": 1
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/customers/xYZkjABcde/orders?filter[q][created_at_gt]=2017-12-12&filter[q][status_eq]=placed&page[number]=1&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/customers/xYZkjABcde/orders?filter[q][created_at_gt]=2017-12-12&filter[q][status_eq]=placed&page[number]=1&page[size]=10"
  }
}
```

{% content-ref url="/pages/-LgSlVz3\_Y6DS2SktOCP" %}
[Pagination](/core/pagination)
{% endcontent-ref %}
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Request" %}
The following request fetches the list of line items of type `skus` associated with a specific order:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/orders/KjajhXvYya/line_items?filter[q][item_type_eq]=skus' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of the related resource objects that match the filter query:

```json
{
  "data": [
    {
      "id": "yzXKjYzaCx",
      "type": "line_items",
      "links": {...},
      "attributes": {
        "sku_code": "TSHIRTMM000000FFFFFFXLXX",
        "bundle_code": null,
        "quantity": 1,
        "currency_code": "USD",
        "unit_amount_cents": 3480,
        "unit_amount_float": 34.8,
        "formatted_unit_amount": "$34.80",
        "options_amount_cents": 0,
        "options_amount_float": 0.0,
        "formatted_options_amount": "$0.00",
        "discount_cents": 0,
        "discount_float": 0.0,
        "formatted_discount": "$0.00",
        "total_amount_cents": 3480,
        "total_amount_float": 34.8,
        "formatted_total_amount": "$34.80",
        "tax_amount_cents": 0,
        "tax_amount_float": 0.0,
        "formatted_tax_amount": "$0.00",
        "name": "Men's Black T-shirt with White Logo (XL)",
        "image_url": "https://img.yourdomain.com/skus/xYZkjABcde.png",
        "discount_breakdown": {},
        "tax_rate": 0.0,
        "tax_breakdown": {},
        "item_type": "skus",
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": null,
        "reference_origin": null,
        "metadata": {}
      },
      "relationships": {
        "order": {
          "links": {...}
        },
        "item": {
          "links": {...}
        },
        "line_item_options": {
          "links": {...}
        },
        "shipment_line_items": {
          "links": {...}
        },
        "stock_line_items": {
          "links": {...}
        },
        "stock_transfers": {
          "links": {...}
        }
      },
      "meta": {
          "mode": "test",
          "organization_id": "JxYabZKcAw"
      }
    },
    {
      "other": "... 2 line items (first page)"
    }
  ],
  "meta": {
    "record_count": 3,
    "page_count": 1
  },
  "links": {
    "first": "https://spineless.commercelayer.io/api/orders/KjajhXvYya/line_items?filter[q][item_type_eq]=skus&page[number]=1&page[size]=10",
    "last": "https://spineless.commercelayer.io/api/orders/KjajhXvYya/line_items?filter[q][item_type_eq]=skus&page[number]=1&page[size]=10"
  }
}
```

{% content-ref url="/pages/-LgSlVz3\_Y6DS2SktOCP" %}
[Pagination](/core/pagination)
{% endcontent-ref %}
{% endtab %}
{% endtabs %}


# Creating resources

How to create a resource via API

You can create a resource by sending a `POST` request to the resources endpoint, with a JSON payload.

{% hint style="warning" %}
The **Content-Type** header must be `application/vnd.api+json`.
{% endhint %}

{% hint style="info" %}
You can get the list of arguments, with type and examples from the documentation of each resource.
{% endhint %}

{% content-ref url="/pages/-LgCGPTjMSTg9sVBpFDk" %}
[Authentication](/core/authentication)
{% endcontent-ref %}

### Example

{% tabs %}
{% tab title="Request" %}
The following request creates a new SKU:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/skus' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "skus",
      "attributes": {
        "code": "TSHIRTMM000000FFFFFFXLXX",
        "name": "Men's Black T-shirt with White Logo (XL)"
      },
      "relationships": {
        "shipping_category": {
          "data": {
            "type": "shipping_categories",
            "id": "zxcVBnMASd"
          }
        }
      }
    }
  }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created resource object:

```json
{
  "data": {
    "id": "xYZkjABcde",
    "type": "skus",
    "links": {
        "self": "https://yourdomain.commercelayer.io/api/skus/xYZkjABcde"
    },
        "attributes": {
            "code": "TSHIRTMM000000FFFFFFXLXX",
            "name": "Men's Black T-shirt with White Logo (XL)",
            "description": null,
            "image_url": null,
            "tag_names": "",
            "pieces_per_pack": null,
            "weight": null,
            "unit_of_weight": null,
            "hs_tariff_number": null,
            "do_not_ship": false,
            "do_not_track": false,
            "created_at": "2018-01-01T12:00:00.000Z",
            "updated_at": "2018-01-01T12:00:00.000Z",
            "reference": null,
            "metadata": {}
        },
        "relationships": {
            "shipping_category": {
                "links": {...}
            },
            "prices": {
                "links": {...}
            },
            "stock_items": {
                "links": {...}
            },
            "delivery_lead_times": {
                "links": {...}
            },
            "sku_options": {
                "links": {...}
            }
        },
        "meta": {
            "mode": "test"
        }
    }
}
```

{% endtab %}
{% endtabs %}


# Updating resources

How to update a resource via API

You can update a resource by sending a `PATCH` request to the resources endpoint, with a JSON payload.

{% hint style="warning" %}
The **Content-Type** header must be `application/vnd.api+json`.
{% endhint %}

{% hint style="info" %}
You can get the list of arguments, with type and examples from the documentation of each resource.
{% endhint %}

{% content-ref url="/pages/-LgCGPTjMSTg9sVBpFDk" %}
[Authentication](/core/authentication)
{% endcontent-ref %}

### Examples

#### Updating attributes

{% tabs %}
{% tab title="Request" %}
The following request updates the description of an existing SKU:

<pre class="language-sh"><code class="lang-sh">curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/skus/xYZkjABcde' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "skus",
    "id": "xYZkjABcde",
<strong>    "attributes": {
</strong><strong>      "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
</strong><strong>    }
</strong>  }
}'
</code></pre>

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the updated resource object:

<pre class="language-javascript"><code class="lang-javascript">{
  "data": {
    "id": "xYZkjABcde",
    "type": "skus",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/skus/xYZkjABcde"
    },
      "attributes": {
        "code": "TSHIRTMM000000FFFFFFXLXX",
        "name": "Men's Black T-shirt with White Logo (XL)",
<strong>        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
</strong>        "image_url": null,
        "tag_names": "",
        "pieces_per_pack": null,
        "weight": null,
        "unit_of_weight": null,
        "hs_tariff_number": null,
        "do_not_ship": false,
        "do_not_track": false,
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": null,
        "metadata": {}
      },
      "relationships": {
        "shipping_category": {
          "links": {...}
        },
        "prices": {
          "links": {...}
        },
        "stock_items": {
          "links": {...}
        },
        "delivery_lead_times": {
          "links": {...}
        },
        "sku_options": {
          "links": {...}
        }
    },
    "meta": {
      "mode": "test"
    }  
  }
}
</code></pre>

{% endtab %}
{% endtabs %}

#### Updating relationships

{% tabs %}
{% tab title="Request" %}
The following request changes the shipping category of an existing SKU:

<pre class="language-sh"><code class="lang-sh">curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/skus/xYZkjABcde' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "skus",
    "id": "xYZkjABcde",
<strong>    "relationships": {
</strong><strong>      "shipping_category": {
</strong><strong>        "data": {
</strong><strong>          "type": "shipping_categories",
</strong><strong>          "id": "ywMJmFPBWA"
</strong><strong>        }
</strong><strong>      }
</strong><strong>    }
</strong>  }
}'
</code></pre>

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the updated resource object:

<pre class="language-json"><code class="lang-json">{
  "data": {
    "id": "xYZkjABcde",
    "type": "skus",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/skus/xYZkjABcde"
    },
      "attributes": {
        "code": "TSHIRTMM000000FFFFFFXLXX",
        "name": "Men's Black T-shirt with White Logo (XL)",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        "image_url": null,
        "tag_names": "",
        "pieces_per_pack": null,
        "weight": null,
        "unit_of_weight": null,
        "hs_tariff_number": null,
        "do_not_ship": false,
        "do_not_track": false,
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": null,
        "metadata": {}
      },
      "relationships": {
<strong>        "shipping_category": {
</strong><strong>          "links": {...}
</strong><strong>        },
</strong>        "prices": {
          "links": {...}
        },
        "stock_items": {
          "links": {...}
        },
        "delivery_lead_times": {
          "links": {...}
        },
        "sku_options": {
          "links": {...}
        }
    },
    "meta": {
      "mode": "test"
    }  
  }
}
</code></pre>

{% endtab %}
{% endtabs %}

#### Removing relationships

{% hint style="info" %}
If a relationship is *optional* for the creation of a resource, it can be removed by sending `PATCH` request with the `data` object set as `null`.
{% endhint %}

{% tabs %}
{% tab title="Request" %}
The following request removes a customer from a customer group:

<pre class="language-sh"><code class="lang-sh">curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/customers/bQWpdhWxVk' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "customers",
    "id": "bQWpdhWxVk",
    "relationships": {
      "customer_group": {
<strong>        "data": null
</strong>      }
    }
  }
}'
</code></pre>

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the updated resource object:

```json
{
  "data": {
    "id": "bQWpdhWxVk",
    "type": "customers",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/customers/bQWpdhWxVk"
    },
    "attributes": {
      "email": "john@example.com",
      "status": "acquired",
      "has_password": true,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "",
      "reference_origin": null,
      "metadata": {}
    },
    "relationships": {
      "customer_group": {
        "links": { ... }
      },
      "customer_addresses": {
        "links": { ... }
      },
      "customer_payment_sources": {
        "links": { ... }
      },
      "customer_subscriptions": {
        "links": { ... }
      },
      "orders": {
        "links": { ... }
      },
      "order_subscriptions": {
        "links": { ... }
      },
      "returns": {
        "links": { ... }
      },
      "sku_lists": {
        "links": { ... }
      },
      "attachments": {
        "links": { ... }
      },
      "events": {
        "links": { ... }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "EnAvaFOrRe"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Tagging resources

How to tag a resource via API

[Most of Commerce Layer's resources](/core-api-reference/tags#taggable-resources) can be tagged using one or more existing [tags](/core-api-reference/tags). To do that, you need to update the resource setting the relationship with the desired tag(s).

{% content-ref url="/pages/-LgSrGVm5cxz3IGx3doV" %}
[Updating resources](/core/updating-resources)
{% endcontent-ref %}

{% hint style="info" %}
A maximum of **10 tags** is allowed for each single resource object.
{% endhint %}

## Example

{% tabs %}
{% tab title="Request" %}
The following request tags the resource identified by the "xYZkjABcde" ID with the two tags identified by the "geJmexflJQ" and "mWJAPvfBaV" IDs:

<pre class="language-shell"><code class="lang-shell">curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/skus/xYZkjABcde' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "skus",
      "id": "xYZkjABcde",
      "relationships": {
<strong>        "tags": {
</strong><strong>          "data": [
</strong><strong>            {
</strong><strong>              "type": "tags",
</strong><strong>              "id": "geJmexflJQ"
</strong><strong>            },
</strong><strong>            {
</strong><strong>              "type": "tags",
</strong><strong>              "id": "mWJAPvfBaV"
</strong><strong>            }
</strong><strong>          ]
</strong><strong>        }
</strong>      }
    }
  }'
</code></pre>

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the updated resource object:

<pre class="language-json"><code class="lang-json">{
  "data": {
    "id": "xYZkjABcde",
    "type": "skus",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/skus/xYZkjABcde"
    },
    "attributes": {
      "code": "TSHIRTMS000000FFFFFFLXXX",
      "name": "Men's Black T-Shirt with White Logo (L)",
      "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
      "image_url": "https://img.yourdomain.com/skus/xYZkjABcde.png",
      "pieces_per_pack": null,
      "weight": null,
      "unit_of_weight": null,
      "hs_tariff_number": null,
      "do_not_ship": false,
      "do_not_track": false,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANYREFEFERNCE",
      "reference_origin": "ANYREFEFERNCEORIGIN",
      "metadata": {}
    },
    "relationships": {
      "shipping_category": { ... },
      "prices": { ... },
      "stock_items": { ... },
      "delivery_lead_times": { ... },
      "sku_options": { ... },
      "attachments": { ... },
      "events": { ... },
<strong>      "tags": {
</strong><strong>        "links": {
</strong><strong>          "self": "https://yourdomain.commercelayer.io/api/skus/xYZkjABcde/relationships/tags",
</strong><strong>          "related": "https://yourdomain.commercelayer.io/api/skus/xYZkjABcde/tags"
</strong><strong>        }
</strong><strong>      }
</strong>    },
    "meta": {
      "mode": "test",
      "organization_id": "YyrQYFzERk"
    }
}
}
</code></pre>

{% endtab %}
{% endtabs %}

## Removing tags

To remove one or more tags from a resource you need to update the resource setting the relationship with the updated list of tags. To remove all the tags from a resource, just set the tags relationship as an empty array.

{% hint style="info" %}
[Deleting a tag](/core-api-reference/tags/delete) automatically removes any existing association.
{% endhint %}

### Example

{% tabs %}
{% tab title="Request" %}
The following request removes all the tags associated with the resource identified by the "xYZkjABcde" ID:

<pre class="language-shell"><code class="lang-shell">curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/skus/xYZkjABcde' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "skus",
      "id": "xYZkjABcde",
      "relationships": {
<strong>        "tags": {
</strong><strong>          "data": []
</strong><strong>        }
</strong>      }
    }
  }'
</code></pre>

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the updated resource object:

```json
{
  "data": {
    "id": "xYZkjABcde",
    "type": "skus",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/skus/xYZkjABcde"
    },
    "attributes": {
      "code": "TSHIRTMS000000FFFFFFLXXX",
      "name": "Men's Black T-Shirt with White Logo (L)",
      "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
      "image_url": "https://img.yourdomain.com/skus/xYZkjABcde.png",
      "pieces_per_pack": null,
      "weight": null,
      "unit_of_weight": null,
      "hs_tariff_number": null,
      "do_not_ship": false,
      "do_not_track": false,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANYREFEFERNCE",
      "reference_origin": "ANYREFEFERNCEORIGIN",
      "metadata": {}
    },
    "relationships": {
      "shipping_category": { ... },
      "prices": { ... },
      "stock_items": { ... },
      "delivery_lead_times": { ... },
      "sku_options": { ... },
      "attachments": { ... },
      "events": { ... },
      "tags": { ... }
    },
    "meta": {
      "mode": "test",
      "organization_id": "YyrQYFzERk"
    }
  }
}
```

{% endtab %}
{% endtabs %}

## Updating the list of tags

If a resource is already associated with one or more tags, tagging the resource by [updating the relationship](#example) will remove all the currently associated tags and replace them with the new list of tags. If you just need to change the list of the tags currently associated with a resource, you can patch the taggable resource and send the trigger attributes `_add_tags` and/or `_remove_tags` specifying the comma-separated list of tag names that you want to add and/or remove.

{% hint style="warning" %}
The specified names must belong to existing tags, meaning that the related tags must be previously [created](/core-api-reference/tags/create). The provided tags are automatically [validated](/core-api-reference/tags#validations) and non-existing ones are ignored and not associated with the resource without returning any errors.
{% endhint %}

{% hint style="info" %}
The two trigger attributes can be sent within the same `PATCH` request (i.e. adding some tags and removing some others in just one API call — [see example](#example-2)). In that case, remember that tag removal is always performed **after** tag addition.
{% endhint %}

### Example

{% tabs %}
{% tab title="Request" %}
The following request changes the list of tags associated with the resource identified by the "xYZkjABcde" ID:

<pre class="language-sh"><code class="lang-sh">curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/skus/xYZkjABcde' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "skus",
      "id": "xYZkjABcde",
      "attributes": {
<strong>        "_add_tags": "out-of-stock,old-collection",
</strong><strong>        "_remove_tags": "new-collection,vip"
</strong>      }
    }
  }'
</code></pre>

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the updated resource object:

```json
{
  "data": {
    "id": "xYZkjABcde",
    "type": "skus",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/skus/xYZkjABcde"
    },
    "attributes": {
      "code": "TSHIRTMS000000FFFFFFLXXX",
      "name": "Men's Black T-Shirt with White Logo (L)",
      "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
      "image_url": "https://img.yourdomain.com/skus/xYZkjABcde.png",
      "pieces_per_pack": null,
      "weight": null,
      "unit_of_weight": null,
      "hs_tariff_number": null,
      "do_not_ship": false,
      "do_not_track": false,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANYREFEFERNCE",
      "reference_origin": "ANYREFEFERNCEORIGIN",
      "metadata": {}
    },
    "relationships": {
      "shipping_category": { ... },
      "prices": { ... },
      "stock_items": { ... },
      "delivery_lead_times": { ... },
      "sku_options": { ... },
      "attachments": { ... },
      "events": { ... },
      "tags": { ... }
    },
    "meta": {
      "mode": "test",
      "organization_id": "YyrQYFzERk"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Deleting resources

How to delete a resource via API

You can delete a resource by sending a `DELETE` request to the resource endpoint.

{% content-ref url="/pages/-LgCGPTjMSTg9sVBpFDk" %}
[Authentication](/core/authentication)
{% endcontent-ref %}

### Example

{% tabs %}
{% tab title="Request" %}
The following request deletes the resource identified by the ID "xYZkjABcde":

```shell
curl -g -X DELETE \
  'https://yourdomain.commercelayer.io/api/skus/xYZkjABcde' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `204 No Content` status code.
{% endtab %}
{% endtabs %}


# Importing resources

How to bulk import resources and their relationships

Commerce Layer lets you import multiple resources in batches. To do that, you need to create a new [import resource](/core-api-reference/imports), specify the `resource_type` you want to import, and populate the `inputs` attribute with a **JSON** (default) or **CSV** list of items. Each element of the `inputs` list (which is an array of objects for JSON and a string for CSV) contains the resource attributes and relationships (at least the ones required for the specific resource to be [created](/core/creating-resources)).

{% hint style="info" %}
To import a CSV list you need to set the `format` attribute to `csv`. Otherwise, if the format is not specified, the import API will assume you're using the default format (JSON) and return an error.
{% endhint %}

{% hint style="warning" %}

#### Points of attention about CSV format imports

* When importing a CSV list of items, you also need to **flatten** the resource attributes and relationships on a single line. The headers for the attributes of a relationship must be prepended by the associated resource name ([see example](#importing-a-list-of-prices-with-price-tiers-csv)).&#x20;
* When importing tags together with a tagged resource, the elements related to the `tags.id` and `tags.name` headers can contain a string with the list of IDs/names, comma separated ([see example](#importing-a-list-of-customers-with-tags-csv)).
* When importing attributes with comma-separated string values, ensure they are correctly escaped ([see the example](#importing-a-list-of-customers-removing-associated-tags-csv)).&#x20;

In general, using CSV is fine for simple imports (resources with a few attributes and no relationship included), otherwise we strongly recommend using JSON to ensure better readability in terms of the `inputs` list.
{% endhint %}

The process is **asynchronous** and you can poll the `status` attribute to [check the import progress](#checking-the-import-status). Once the import has been completed you can check the number of imported items by inspecting the `processed_count` attribute. In case of [validation errors](#handling-import-errors), the `errors_count` and `errors_log` attributes are populated.

{% hint style="info" %}
Resource relationships can be addressed by using their IDs. To do that, you need to append the `_id` suffix to the name of the related resource (e.g. `price_list_id`). Some relationships can also be specified as a nested array of objects (e.g. [order line items](#importing-a-list-of-orders-with-line-items-and-line-item-options-json), [price tiers](#importing-a-list-of-prices-with-price-tier-csv), [SKU list items](#importing-a-list-of-sku-lists-with-sku-list-items-json), etc.).
{% endhint %}

{% hint style="warning" %}
Some automations normally triggered on resources' creation or update (e.g. webhooks, callbacks, and most event-driven communications) might not be enabled when using imports. Read [here](#disabled-automations) for more information.
{% endhint %}

## Attachment URL

When an import is started, the data you pass within the `inputs` list is validated, compressed ([gzip](https://www.gzip.org/)), and then uploaded to an external storage service (currently [Amazon S3](https://aws.amazon.com/s3/)). You can download the imported data using the link exposed in the `attachment_url` attribute, which is populated as soon as the import is completed.

{% hint style="info" %}
External storage service URLs expire in **5 minutes**. You need to uncompress (`gunzip`) the file in order to read the data back. If the imported data URL is expired you can just [fetch the completed import](#checking-the-import-status) to get a new working one.
{% endhint %}

## Import limits

### Maximum import size

There is no limit on the total number of resources you can import, but the single batches are subject to some soft limits: the `inputs` array must contain a maximum of **10000** items, otherwise the import will be rejected at the time of creation.

### Maximum error percentage

During the import process, the errors count is also monitored: imports whose `errors_count` attribute value overflows the maximum percentage of **10%** of the total import size (i.e. the number of items contained in the `inputs` array) will be interrupted.

{% hint style="info" %}
When necessary, you can disable the import interruption even if the number of its errors exceeds the 10% threshold by setting  `skip_errors` parameter to `true` (default is `false`) on the specific import.
{% endhint %}

### Concurrent imports

The maximum number of concurrent imports (i.e. imports whose status is `pending` or `in_progess`) allowed per organization is **10**.

{% hint style="info" %}
If you absolutely need to import any of the [supported resources](#supported-resources) in one go, overriding the maximum import size and concurrent imports API limits above, you can leverage the power of our [CLI import plugin](https://github.com/commercelayer/commercelayer-cli-plugin-imports/) ([see example](#importing-more-than-10k-gift-cards-using-the-cli)).
{% endhint %}

## Supported resources

At the moment, imports are available for the following resources (more to come):

* Addresses
* Bundles
* Coupons
* Customer addresses
* Customer payment sources
* Customer subscriptions
* Customers
* Gift cards
* Line items
* Line item options
* Orders
* Price tiers
* Prices
* Shipping categories
* SKU list items
* SKU lists
* SKU options
* SKUs
* Stock items
* Stock transfers
* Tags
* Tax categories

Please find some examples of how to import them [here below](#examples).

{% hint style="info" %}
With very few exceptions (e.g. shipments, transactions, etc.) you can use as `inputs` any output (both in JSON or CSV format) you get from the [exports API](/core/exporting-resources).
{% endhint %}

{% content-ref url="/pages/94BUWUKkf25IMXzSXwoT" %}
[Exporting resources](/core/exporting-resources)
{% endcontent-ref %}

## Unique keys

{% hint style="info" %}
If the single resource to be imported doesn't exist it gets created, otherwise it is updated.
{% endhint %}

In order to detect if a resource already exists the `id` key is checked for each `inputs` array element. Some resources also support specific (combined) attributes to identify an existing record, which can be helpful in case the resource ID isn't known during the import process:

* Bundles — `code` + `market_id`
* Coupons — `code` + `promotion_rule_id`
* Customer addresses — `customer_id`
* Customer subscriptions — `customer_id` + `reference`
* Customers — `email`
* Gift cards — `code`
* Orders — `number`
* Prices — `sku_code` + `price_list_id`
* Shipping categories — `name`
* SKU options — `name` + `currency_code`
* SKUs — `code`
* Stock items — `sku_code` + `stock_location_id`
* Tags — `name`
* Tax categories — `code` + `tax_calculator_id`

{% hint style="warning" %}
In case both the specific unique key and the `id` are passed, the latter is used to identify existing records to be updated. This way is possible to modify the value of the specific unique key with a new one (i.e. changing the `code` of an SKU or the `number` of an [order](/core-api-reference/orders#changing-the-order-number)). Keep in mind that in this case every entry of the `inputs` array must have the `id` key, otherwise the specific key is used to identify the record and the import result could not be as expected (e.g. new records could be created instead of updating existing ones).
{% endhint %}

## Specifying the parent resource

If the resources you're importing refer to the same parent resource (e.g. prices to the same price list), you can avoid repeating its value on each inputs items by specifying the `parent_resource_id` attribute. In case you specify both the parent resource ID and the relationship ID for each item, the latter wins. These are the supported parent resources:

* Bundles — `market_id`
* Coupons — `promotion_rule_id`
* Customer payment sources — `payment_method_id`
* Gift cards — `market_id`
* Orders — `market_id`
* Prices — `price_list_id`
* SKU list items — `sku_list_id`
* SKU options — `market_id`
* Stock items — `stock_location_id`
* Tax categories — `tax_calculator_id`

## Disabled automations

### Webhooks

Excluding those associated with order status change events (`orders.place`, `orders.approve`, `orders.cancel`, `orders.authorize`, `orders.void`, `orders.pay`, `orders.refund`, `orders.start_fulfilling`, `orders.cancel_fulfilling`, and `orders.fulfill`), during imports all of the [real-time webhooks](/core/real-time-webhooks) are disabled.

In case you need to leverage all the other real-time events you have to create/update resources via the related API endpoints.

### After-save callbacks

All of the resource's after-save callbacks are not executed on imports. This means that some attributes dependent on such callbacks will not be persisted (i.e. timestamps after status change or numbers set with the ID value).

In case you need to run after-save callbacks you have to make standard CRUD actions via the related API endpoints.

## Cleaning-up records

If you need to remove some resources and their associated relationships before or after importing new ones we suggest leveraging the [cleanups](/core-api-reference/cleanups) endpoint, making sure to use a valid [filter](/core/cleaning-resources#filtering-the-data-to-be-removed) and include the necessary relationships.

{% hint style="warning" %}
Just to be sure you can rollback, we strongly recommend to perform an [export](/core/exporting-resources) using the very same [filter](/core/exporting-resources#filtering-exported-data) before any cleanup operation.
{% endhint %}

{% content-ref url="/pages/nvCxKPEJZjWHqNOFqs4T" %}
[Cleaning up resources](/core/cleaning-resources)
{% endcontent-ref %}

## Examples

### Importing a list of addresses (CSV) <a href="#importing-a-list-of-addresses-csv" id="importing-a-list-of-addresses-csv"></a>

{% tabs %}
{% tab title="Request" %}
The following request creates an import with a list of addresses in CSV format:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/imports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "imports",
      "attributes": {
        "resource_type": "addresses",
        "format": "csv",
        "inputs": "first_name,last_name,company,line_1,city,zip_code,state_code,country_code,phone,email\nGeorge,Harrison,The Beatles,Viale Borgo Valsugana 93,Prato,59100,PO,IT,+39 0574 933550,george@thebeatles.co.uk\n"
      }
    }
  }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created import object:

```json
{
  "data": {
    "id": "PmjlkIJzRA",
    "type": "imports",
    "links": { ... },
    "attributes": {
      "resource_type": "addresses",
      "format": "csv",
      "parent_resource_id": null,
      "status": "pending",
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "inputs": "...",
      "inputs_size": 100,
      "errors_count": 0,
      "warnings_count": 0,
      "destroyed_count": 0,
      "processed_count": 0,
      "cleanup_records": false,
      "attachment_url": nil,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": { ... }
  }
}
```

{% endtab %}
{% endtabs %}

For a list of all the required attributes you need to create an address, refer to the [related section](/core-api-reference/addresses/create) of the API reference.

### Importing a list of bundles (JSON)

{% tabs %}
{% tab title="Request" %}
The following request creates an import with a list of bundles in JSON format:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/imports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "imports",
      "attributes": {
        "resource_type": "bundles",
        "parent_resource_id": "bgOEQhznoZ",
        "inputs": [
          {
            "code":"FWOUTFIT",
            "name":"FW outfit",
            "image_url":"https://img.yourdomain.com/bundles/FWOUTFIT.png",
            "reference": "FWOUTFIT",
            "sku_list_id": "GHYfrWszHp"
          },
          {
            "code":"SSOUTFIT",
            "name":"SS outfit",
            "image_url":"https://img.yourdomain.com/bundles/SSOUTFIT.png",
            "reference": "SSOUTFIT",
            "sku_list_id": "GHYfrWszHp"
          },
          { ... }
        ]
      }
    }
  }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created import object:

```json
{
  "data": {
    "id": "PmjlkIJzRA",
    "type": "imports",
    "links": { ... },
    "attributes": {
      "resource_type": "bundles",
      "format": "json",
      "parent_resource_id": "bgOEQhznoZ",
      "status": "pending",
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "inputs": [ ... ],
      "inputs_size": 100,
      "errors_count": 0,
      "warnings_count": 0,
      "destroyed_count": 0,
      "processed_count": 0,
      "cleanup_records": false,
      "attachment_url": nil,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": { ... }
  }
}
```

{% endtab %}
{% endtabs %}

For a list of all the required attributes you need to create a bundle, refer to the [related section](/core-api-reference/bundles/create) of the API reference.

### Importing a list of coupons (CSV)

{% tabs %}
{% tab title="Request" %}
The following request creates an import with a list of coupons in CSV format and clean-up the ones existing for the same promotion rule:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/imports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "imports",
      "attributes": {
        "resource_type": "coupons",
        "format": "csv",
        "parent_resource_id": "FreQKlNxZA",
        "inputs": "code,customer_single_use,usage_limit,usage_count,recipient_email\n11111111,false,,0,\n22222222,false,,0,\n33333333,false,,0,george@harrison.co.uk\n"
      }
    }
   }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created import object:

```json
{
  "data": {
    "id": "PmjlkIJzRA",
    "type": "imports",
    "links": { ... },
    "attributes": {
      "resource_type": "coupons",
      "format": "csv",
      "parent_resource_id": "FreQKlNxZA",
      "status": "pending",
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "inputs": "...",
      "inputs_size": 3,
      "errors_count": 0,
      "warnings_count": 0,
      "destroyed_count": 0,
      "processed_count": 0,
      "cleanup_records": false,
      "attachment_url": nil,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": { ... }
  }
}
```

{% endtab %}
{% endtabs %}

For a list of all the required attributes you need to create a coupon, refer to the [related section](/core-api-reference/coupons/create) of the API reference.

### Importing a list of customer addresses (JSON)

{% tabs %}
{% tab title="Request" %}
The following request creates an import with a list of customer addresses in JSON format (the associated address can be either specified by ID if existing or created if not existing):

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/imports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "imports",
      "attributes": {
        "resource_type": "customer_addresses",
        "inputs": [
          {
            "customer_email": "john@example.com",
            "address_id": "gHbVCxZSdE"
          },
          {
            "customer_email": "mario@example.com",
            "address": { 
              "first_name": "Mario", 
              "last_name": "Rossi", 
              "line_1": "Viale Borgo Valsugana 7", 
              "city": "Prato", 
              "zip_code": "59100", 
              "state_code": "PO", 
              "country_code": "IT", 
              "phone": "+39 0574 933550"
            }
          },
          { ... }
        ]
      }
    }
  }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created import object:

```json
{
  "data": {
    "id": "NqYzgIKvdm",
    "type": "imports",
    "links": { ... },
    "attributes": {
      "resource_type": "customer_addresses",
      "format": "json",
      "parent_resource_id": null,
      "status": "pending",
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "inputs": [ ... ],
      "inputs_size": 100,
      "errors_count": 0,
      "warnings_count": 0,
      "destroyed_count": 0,
      "processed_count": 0,
      "errors_log": {},
      "warnings_log": {},
      "cleanup_records": false,
      "attachment_url": nil,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": { ... }
  }
}
```

{% endtab %}
{% endtabs %}

### Importing a list of customer payment sources (JSON)

{% tabs %}
{% tab title="Request" %}
The following request creates an import with a list of customer payment sources in JSON format (you must always provide the `customer_token` and `payment_source_token` you've got from your payment gateway):

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/imports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "imports",
      "attributes": {
        "resource_type": "customer_payment_sources",
        "parent_resource_id": "hgTfDcXXzs",
        "inputs": [
          {
            "customer_token": "255203791",
            "payment_source_token: "5f8k2cr",
            "customer_id": "hGdEwsAqlK"
          },
          {
            "customer_token": "255265209",
            "payment_source_token: "6gh02cz",
            "customer_id": "jHgfTTrcVn"
          },
          { ... }
        ]
      }
    }
  }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created import object:

```json
{
  "data": {
    "id": "NqYzgIKvdm",
    "type": "imports",
    "links": { ... },
    "attributes": {
      "resource_type": "customer_payment_sources",
      "format": "json",
      "parent_resource_id": "hgTfDcXXzs",
      "status": "pending",
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "inputs": [ ... ],
      "inputs_size": 100,
      "errors_count": 0,
      "warnings_count": 0,
      "destroyed_count": 0,
      "processed_count": 0,
      "errors_log": {},
      "warnings_log": {},
      "cleanup_records": false,
      "attachment_url": nil,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": { ... }
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
To create an import of customer payment sources you must always provide the `customer_token` and `payment_source_token` you got from your payment gateway.
{% endhint %}

For a list of all the required attributes you need to create a customer payment sources, refer to the [related section](/core-api-reference/customer_payment_sources/create) of the API reference.

### Importing a list of customer subscriptions (JSON)

{% tabs %}
{% tab title="Request" %}
The following request creates an import with a list of customer subscriptions in JSON format:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/imports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "imports",
      "attributes": {
        "resource_type": "customer_subscriptions",
        "inputs": [
          {
            "customer_email": "john@example.com",
            "reference": "Marketing newsletter"
          },
          {
            "customer_email": "jane@example.com",
            "reference": "Whitepaper download"
          },
          { ... }
        ]
      }
    }
  }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created import object:

```json
{
  "data": {
    "id": "NqYzgIKvdm",
    "type": "imports",
    "links": { ... },
    "attributes": {
      "resource_type": "customer_subscriptions",
      "format": "json",
      "parent_resource_id": null,
      "status": "pending",
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "inputs": [ ... ],
      "inputs_size": 100,
      "errors_count": 0,
      "warnings_count": 0,
      "destroyed_count": 0,
      "processed_count": 0,
      "errors_log": {},
      "warnings_log": {},
      "cleanup_records": false,
      "attachment_url": nil,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": { ... }
  }
}
```

{% endtab %}
{% endtabs %}

For a list of all the required attributes you need to create a customer subscription, refer to the [related section](/core-api-reference/customer_subscriptions/create) of the API reference.

### Importing a list of customers (CSV)

{% tabs %}
{% tab title="Request" %}
The following request creates an import with a list of customers in CSV format:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/imports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "imports",
      "attributes": {
        "resource_type": "customers",
        "format": "csv",
        "inputs": "email,password,customer_group_id\njohn@example.com,,\njack@example.com,secret,KngqdhAlpd\n"
      }
    }
  }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created import object:

```json
{
  "data": {
    "id": "ZqDQzIoznm",
    "type": "imports",
    "links": { ... },
    "attributes": {
      "resource_type": "customers",
      "format": "csv",
      "parent_resource_id": null,
      "status": "pending",
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "inputs": "...",
      "inputs_size": 100,
      "errors_count": 0,
      "warnings_count": 0,
      "destroyed_count": 0,
      "processed_count": 0,
      "errors_log": {},
      "warnings_log": {},
      "cleanup_records": false,
      "attachment_url": nil,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": { ... }
  }
}
```

{% endtab %}
{% endtabs %}

For a list of all the required attributes you need to create a customer, refer to the [related section](/core-api-reference/customers/create) of the API reference.

### Importing a list of gift cards (JSON)

{% tabs %}
{% tab title="Request" %}
The following request creates an import with a list of gift cards in JSON format:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/imports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "imports",
      "attributes": {
        "resource_type": "gift_cards",
        "parent_resource_id": "bgOEQhznoZ",
        "inputs": [
          {
            "balance_cents": 12500,
            "currency_code": "USD",
            "single_use": false,
            "rechargeable": true,
            "image_url": "https://img.yourdomain.com/skus/MYGITFCARDIMAGE.png",
            "expires_at": "2030-01-01T00:00:00Z",
            "recipient_email": "john@example.com"
          },
          {
            "balance_cents": 20000,
            "currency_code": "EUR",
            "single_use": true,
            "rechargeable": false,
            "expires_at": "2025-01-01T00:00:00Z",
            "recipient_email": "jane@example.com"
          },
          { ... }
        ]
      }
    }
  }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created import object:

```json
{
  "data": {
    "id": "BAzkwIRNkq",
    "type": "imports",
    "links": { ... },
    "attributes": {
      "resource_type": "gift_cards",
      "format": "json",
      "parent_resource_id": "bgOEQhznoZ",
      "status": "pending",
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "inputs": [ ... ],
      "inputs_size": 100,
      "errors_count": 0,
      "warnings_count": 0,
      "destroyed_count": 0,
      "processed_count": 0,
      "errors_log": {},
      "warnings_log": {},
      "cleanup_records": false,
      "attachment_url": nil,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": { ... }
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
To create an import of gift cards for the same **market**, remember to specify its ID as the`parent_resource_id` attribute. On the other hand, specifying the `market_id` or the `market_code` attributes for every single item of the `inputs` list lets you import gift cards associated with different markets all at once.
{% endhint %}

For a list of all the required attributes you need to create a gift card, refer to the [related section](/core-api-reference/gift_cards/create) of the API reference.

### Importing a list of orders with line items and line item options (JSON)

{% tabs %}
{% tab title="Request" %}
The following request creates an import with a list of orders with associated line items and line item options in JSON format:

<pre class="language-shell"><code class="lang-shell">curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/imports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": { 
      "type": "imports",
      "attributes": {
        "resource_type": "orders",
				"parent_resource_id": "KmjljGJzWQ",
        "inputs": [
          {
            "customer_email": "john@example.com",
            "line_items": [
              {
                "item_type": "skus",
                "name": "Black Hat Size M",
                "quantity": 2,
                "unit_amount_cents": 1000,
                "line_item_options": [
                  { 
                    "name": "engraving", 
                    "sku_option_id": "GhFDsAWqRU",
                    "quantity": 1 
                  }, 
                  {  
                    "name": "embossing",
                    "sku_option_id": "hJgFCvBNmK",
                    "quantity": 2 
                  }
                ]
              },
              { 
                "item_type": "skus",
                "name": "White T-shirt Size XL",
                "quantity": 1,
                "unit_amount_cents": 2000
              }
            ]
          },
          {
            "customer_email": "jack@example.com",
<strong>            "_archive": 1,
</strong><strong>            "status": "cancelled",
</strong><strong>            "cancelled_at": "2018-01-01T12:00:00.000Z",
</strong>            "line_items": [
              { 
                "item_type": "skus",
                "name": "Black T-Shirt Size S",
                "quantity": 2,
                "unit_amount_cents": 1500
              }
            ]
          },
          { ... }
        ]
      }
    }
  }'
</code></pre>

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created import object:

```json
{
  "data": {
    "id": "PmjlkIJzRA",
    "type": "imports",
    "links": { ... },
    "attributes": {
      "resource_type": "orders",
      "format": "json",
      "parent_resource_id": "KmjljGJzWQ",
      "status": "pending",
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "inputs": [ ... ],
      "inputs_size": 100,
      "errors_count": 0,
      "warnings_count": 0,
      "destroyed_count": 0,
      "processed_count": 0,
      "errors_log": {},
      "warnings_log": {},
      "cleanup_records": false,
      "attachment_url": nil,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": { ... }
  }
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
To create an import of orders for the same **market**, remember to specify its ID as the `parent_resource_id` attribute. On the other hand, specifying the `market_id` or the `market_code` attributes for every single item of the `inputs` list lets you import orders associated with different markets all at once.
{% endhint %}

{% hint style="warning" %}
To bypass some of the order's standard validations and avoid any issues, we strongly recommend passing the `_archive` trigger attribute when importing orders that are in a status different from `draft` and `pending`. This way, the orders will be automatically archived and you will be allowed to specify also some attributes that normally are not [updatable](/core-api-reference/orders/update) `status`, `payment_status`, `fulfillment_status`, `placed_at`, `approved_at`, `cacelled_at`, `payment_updated_at`, and `fulfillment_updated_at`) — just make sure to be consistent when doing that (e.g. if you define a `cancelled_at` datetime, set the order status to `cancelled` accordingly).
{% endhint %}

For a list of all the required attributes you need to create an order, refer to the [related section](/core-api-reference/orders/create) of the API reference.

### Importing a list of prices with price tiers (CSV)

{% tabs %}
{% tab title="Request" %}
The following request creates an import with a list of prices and the associated price tiers in CSV format:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/imports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "imports",
      "attributes": {
        "resource_type": "prices",
        "format": "csv",
        "parent_resource_id": "vLrWRCJWBE",
        "inputs": "currency_code,sku_code,amount_cents,compare_at_amount_cents,price_tiers.type,price_tiers.name,price_tiers.up_to,price_tiers.price_amount_cents\nEUR,REDHANDBAG,1000,1000,PriceVolumeTier,10 pack,10,600\nEUR,REDHANDBAG,1000,1000,PriceVolumeTier,20 pack,20,400\nEUR,BLUEHANDBAG,2000,2000,PriceVolumeTier,XL pack,,300\n"
      }
    }
  }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created import object:

```json
{
  "data": {
    "id": "ZbDQzIoxnA",
    "type": "imports",
    "links": { ... },
    "attributes": {
      "resource_type": "prices",
      "format": "csv",
      "parent_resource_id": "vLrWRCJWBE",
      "status": "pending",
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "inputs": "...",
      "inputs_size": 45,
      "errors_count": 0,
      "warnings_count": 0,
      "destroyed_count": 0,
      "processed_count": 0,
      "cleanup_records": false,
      "attachment_url": nil,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": { ... }
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
To create an import of prices for the same **price list**, remember to specify its ID as the `parent_resource_id` attribute. On the other hand, specifying the `price_list_id` or the `price_list_code` attributes for every single item of the `inputs` list lets you import prices associated with different price lists all at once.
{% endhint %}

For a list of all the required attributes you need to create a price, refer to the [related section](/core-api-reference/prices/create) of the API reference. More info about price volume tiers [here](https://github.com/commercelayer/commercelayer-docs-api/blob/master/broken-reference/README.md).

### Importing a list of SKU lists with SKU list items (JSON)

{% tabs %}
{% tab title="Request" %}
The following request creates an import with a list of SKU lists with associated SKU list items in JSON format:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/imports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
    "type": "imports",
      "attributes": {
        "resource_type": "sku_lists",
        "inputs": [
          {
            "name":"Promotional Items 15%",
            "sku_list_items": [
              { 
                "sku_code": "BABYONBU000000E63E7667MX",
              },
              { 
                "sku_code": "BABYONBU000000E63E7418MX",
              }
            ]
          },
          { ... }
        ]
      }
    }
  }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created import object:

```json
{
  "data": {
    "id": "PmjlkIJzRA",
    "type": "imports",
    "links": { ... },
    "attributes": {
      "resource_type": "sku_lists",
      "format": "json",
      "parent_resource_id": null,
      "status": "pending",
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "inputs": [ ... ],
      "inputs_size": 100,
      "errors_count": 0,
      "warnings_count": 0,
      "destroyed_count": 0,
      "processed_count": 0,
      "cleanup_records": false,
      "attachment_url": nil,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": { ... }
  }

```

{% endtab %}
{% endtabs %}

For a list of all the required attributes you need to create an SKU list, refer to the [related section](/core-api-reference/sku_lists/create) of the API reference.

### Importing a list of SKU options (CSV)

{% tabs %}
{% tab title="Request" %}
The following request creates an import with a list of SKU options in CSV format:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/imports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "imports",
      "attributes": {
        "resource_type": "sku_options",
        "format": "csv",
        "parent_resource_id": "XHnLEsQaZp",
        "inputs": "name,price_amount_cents,sku_code_regex\n,engraving,500,^A\nshipping costs,700,^B\n"
      }
    }
  }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created import object:

```json
{
  "data": {
    "id": "PmjlkIJzRA",
    "type": "imports",
    "links": { ... },
    "attributes": {
      "resource_type": "sku_options",
      "format": "csv",
      "parent_resource_id": "XHnLEsQaZp",
      "status": "pending",
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "inputs": "...",
      "inputs_size": 2,
      "errors_count": 0,
      "warnings_count": 0,
      "destroyed_count": 0,
      "processed_count": 0,
      "cleanup_records": false,
      "attachment_url": nil,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": { ... }
  }

```

{% endtab %}
{% endtabs %}

For a list of all the required attributes you need to create an SKU option, refer to the [related section](/core-api-reference/sku_options/create) of the API reference.

### Importing a list of SKUs (JSON)

{% tabs %}
{% tab title="Request" %}
The following request creates an import with a list of SKUs in JSON format:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/imports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "imports",
      "attributes": {
        "resource_type": "skus",
        "inputs": [
          {
            "code":"BABYONBU000000E63E7424MX",
            "name":"Baby's Black Onesie Short Sleeve with Pink Logo (24 Months)",
            "image_url":"https://img.yourdomain.com/skus/BABYONBU000000E63E74.png",
            "reference": "BABYONBU000000E63E74",
            "shipping_category_code": "2_days"
          },
          {
            "code":"BABYONBU000000E63E7418MX",
            "name":"Baby's Black Onesie Short Sleeve with Pink Logo (18 Months)",
            "image_url":"https://img.yourdomain.com/skus/BABYONBU000000E63E74.png",
            "reference": "BABYONBU000000E63E74",
            "shipping_category_id": "zwzQeFBrNj"
          },
          { ... }
        ]
      }
    }
 }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created import object:

```json
{
  "data": {
    "id": "PmjlkIJzRA",
    "type": "imports",
    "links": { ... },
    "attributes": {
      "resource_type": "skus",
      "format": "json",
      "parent_resource_id": null,
      "status": "pending",
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "inputs": [ ... ],
      "inputs_size": 100,
      "errors_count": 0,
      "warnings_count": 0,
      "destroyed_count": 0,
      "processed_count": 0,
      "cleanup_records": false,
      "attachment_url": nil,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": { ... }
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
SKUs have no [parent resource](#specifying-the-parent-resource), hence the shipping category cannot be used as the `parent_resource_id` attribute. On the other hand, specifying the `shipping_category_id` or the `shipping_category_code` attributes for every single item of the `inputs` list lets you import SKUs associated with different shipping categories all at once (SKUs marked as `do_not_ship` included, for which you just can avoid setting any `shipping_category_id` at all).
{% endhint %}

For a list of all the required attributes you need to create an SKU, refer to the [related section](/core-api-reference/skus/create) of the API reference.

### Importing a list of stock items (CSV)

{% tabs %}
{% tab title="Request" %}
The following request creates an import with a list of stock items in CSV format:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/imports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "imports",
      "attributes": {
        "resource_type": "stock_items",
        "format": "csv",
        "parent_resource_id": "bnEeQuqZgn",
        "inputs": "sku_code,quantity,_validate\nBABYONBU000000E63E7424MX,110,1\nBABYONBU000000E63E7418MX,140,1\n"
      }
    }
  }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created import object:

```json
{
  "data": {
    "id": "YqQJGIYWjm",
    "type": "imports",
    "links": { ... },
    "attributes": {
      "resource_type": "stock_items",
      "format": "csv",
      "parent_resource_id": "bnEeQuqZgn",
      "status": "pending",
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "inputs": "...",
      "inputs_size": 2,
      "errors_count": 0,
      "warnings_count": 0,
      "destroyed_count": 0,
      "processed_count": 0,
      "cleanup_records": false,
      "attachment_url": nil,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": { ... }
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
To create an import of stock items for the same **stock location**, remember to specify the stock location ID as the `parent_resource_id` attribute. On the other hand, specifying the `stock_location_id` or the `stock_location_code` attributes for every single item of the `inputs` list lets you import stock items associated with different stock locations all at once.
{% endhint %}

{% hint style="warning" %}
When importing stock items, existing records may be updated with inconsistent quantities: this occurs when the quantity of a stock item is less than the existing reserved stock, which is probably an overselling symptom. To avoid this scenario, we recommend passing the `_validate` trigger attribute for each of the imported inputs: in case the `quantity` is smaller than the associated `reserved_stock,` the update fails and an error is logged for further inspection.
{% endhint %}

For a list of all the required attributes you need to create a stock item, refer to the [related section](/core-api-reference/stock_items/create) of the API reference.

### Importing a list of stock transfers (JSON)

{% tabs %}
{% tab title="Request" %}
The following request creates an import with a list of stock transfers in JSON format:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/imports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "imports",
      "attributes": {
        "resource_type": "stock_transfers",
        "format": "json",
        "inputs": [
          {
            "sku_code":"BABYONBU000000E63E7424MX",
            "quantity":2,
            "origin_stock_location_id": "ondYzudReG",
            "destination_stock_location_id": "znmoyuXpYk"
          },
          {
            "sku_code":"BABYONBU000000E63E7418MX",
            "quantity":3,
            "origin_stock_location_code": "EUCOM",
            "destination_stock_location_code": "EUWHR"
          },
          { ... }
        ]
      }
    }
  }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created import object:

```json
{
  "data": {
    "id": "YqQJGIYWjm",
    "type": "imports",
    "links": { ... },
    "attributes": {
      "resource_type": "stock_transfers",
      "format": "json",
      "parent_resource_id": null,
      "status": "pending",
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "inputs": "...",
      "inputs_size": 2,
      "errors_count": 0,
      "warnings_count": 0,
      "destroyed_count": 0,
      "processed_count": 0,
      "cleanup_records": false,
      "attachment_url": nil,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": { ... }
  }
}
```

{% endtab %}
{% endtabs %}

For a list of all the required attributes you need to create a stock transfer, refer to the [related section](/core-api-reference/stock_transfers/create) of the API reference.

### Importing a list of tags (CSV)

{% tabs %}
{% tab title="Request" %}
The following request creates an import with a list of tags in CSV format:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/imports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "imports",
      "attributes": {
        "resource_type": "tags",
        "format": "csv",
        "inputs": "name\nbags\nhats\naccessories"
      }
    }
  }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created import object:

```json
{
  "data": {
    "id": "amJNpILdxm",
    "type": "imports",
    "links": { ... },
    "attributes": {
      "resource_type": "tags",
      "format": "csv",
      "parent_resource_id": null,
      "status": "pending",
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "inputs": "...",
      "inputs_size": 3,
      "errors_count": 0,
      "warnings_count": 0,
      "destroyed_count": 0,
      "processed_count": 0,
      "errors_log": {},
      "warnings_log": {},
      "cleanup_records": null,
      "attachment_url": nil,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "relationships": { ... },
    "meta": { ... }
  }

```

{% endtab %}
{% endtabs %}

For a list of all the required attributes you need to create a tag, refer to the [related section](/core-api-reference/tags/create) of the API reference.

### Importing a list of SKUs with tags (JSON)

{% tabs %}
{% tab title="Request" %}
The following request creates an import with a list of SKUs and the associated tags in JSON format:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/imports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "imports",
      "attributes": {
        "resource_type": "skus",
        "parent_resource_id": "BNdxyFenNG",
        "inputs": [
          {
            "code": "TSHIRTMS000000FFFFFFLXXX",
            "name": "Men's Black T-Shirt with White Logo (L)",
            "tags": [
              {
                "name": "t_shirts"
              }
            ]
          },
          {
            "code": "TOYCARMINICOUNTRYMANYB",
            "name": "Toy Car — Mini Countryman, Yellow/Black",
            "tags": [
              {
                "name": "toys"
              },
              {
                "name": "black_friday"
              }
            ]
          },
          {
            "code": "BASEBCAPLABLUE",
            "name": "Baseball Cap LA, Blue",
            "tags": [
              {
                "name": "black_friday"
              },
              {
                "name": "hats"
              },
              {
                "name": "new_collection"
              }
            ]
          }
        ]
      }
    }
  }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created import object:

```json
{
    "data": {
      "id": "OqPnLIpDxb",
      "type": "imports",
      "links": { ... },
      "attributes": {
        "resource_type": "skus",
        "format": "json",
        "parent_resource_id": "BNdxyFenNG",
        "status": "pending",
        "started_at": null,
        "completed_at": null,
        "interrupted_at": null,
        "inputs": [ ... ],
        "inputs_size": 3,
        "errors_count": 0,
        "warnings_count": 0,
        "destroyed_count": 0,
        "processed_count": 0,
        "errors_log": {},
        "warnings_log": {},
        "cleanup_records": null,
        "attachment_url": "https://download_link.amazonaws.com/imports_...",
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": null,
        "reference_origin": null,
        "metadata": {}
    },
    "relationships": { ... },
    "meta": { ... }
  }
}
```

{% endtab %}
{% endtabs %}

For a list of all the required attributes you need to create a SKU, refer to the [related section](/core-api-reference/skus/create) of the API reference. More info about tags [here](/core-api-reference/tags).

### Importing a list of customers with tags (CSV)

{% tabs %}
{% tab title="Request" %}
The following request creates an import with a list of customers and the associated tags in CSV format:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/imports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "imports",
      "attributes": {
        "resource_type": "customers",
        "format": "csv",
        "inputs": "email,tags.id,tags.name\njohn@example.com,\"\",\"newsletter\"\njane@example.com,\"\",\"vip,black_friday\""
      }
    }
  }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created import object:

```json
{
  {
    "data": {
      "id": "BAzkwIeoZq",
      "type": "imports",
      "links": { ... },
      "attributes": {
        "resource_type": "customers",
        "parent_resource_id": null,
        "status": "pending",
        "started_at": null,
        "completed_at": null,
        "interrupted_at": null,
        "inputs": [ ... ],
        "inputs_size": 2,
        "errors_count": 0,
        "warnings_count": 0,
        "destroyed_count": 0,
        "processed_count": 0,
        "errors_log": {},
        "warnings_log": {},
        "cleanup_records": null,
        "attachment_url": nil,
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": null,
        "reference_origin": null,
        "metadata": {}
      },
      "relationships": { ... },
      "meta": { ... }
    }
  }
}
```

{% endtab %}
{% endtabs %}

For a list of all the required attributes you need to create a customer, refer to the [related section](/core-api-reference/customers/create) of the API reference. More info about tags [here](/core-api-reference/tags).

### Importing a list of customers removing the associated tags (CSV)

{% tabs %}
{% tab title="Request" %}
The following request creates an import with a list of customers in CSV format, removing the associated tags:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/imports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "imports",
      "attributes": {
        "resource_type": "customers",
        "format": "csv",
        "inputs": "email,_remove_tags\njane@example.com,\"vip,black_friday\""
      }
    }
  }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created import object:

```json
{
  {
    "data": {
      "id": "BAzkwIeoZq",
      "type": "imports",
      "links": { ... },
      "attributes": {
        "resource_type": "customers",
        "parent_resource_id": null,
        "status": "pending",
        "started_at": null,
        "completed_at": null,
        "interrupted_at": null,
        "inputs": [ ... ],
        "inputs_size": 1,
        "errors_count": 0,
        "warnings_count": 0,
        "destroyed_count": 0,
        "processed_count": 0,
        "errors_log": {},
        "warnings_log": {},
        "cleanup_records": null,
        "attachment_url": nil,
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": null,
        "reference_origin": null,
        "metadata": {}
      },
      "relationships": { ... },
      "meta": { ... }
    }
  }
}
```

{% endtab %}
{% endtabs %}

For a list of all the required attributes you need to create a customer, refer to the [related section](/core-api-reference/customers/create) of the API reference. More info about tags [here](/core-api-reference/tags).

### Importing a list of tax categories (CSV)

{% tabs %}
{% tab title="Request" %}
The following request creates an import with a list of tax categories in CSV format:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/imports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "imports",
      "attributes": {
        "resource_type": "tax_categories",
        "format": "csv",
        "parent_resource_id": "daSWQhzjkiZ",
        "inputs": "sku_code,code\nBABYONBU000000E63E7424MX,31000\nBABYONBU000000E63E7418MX,31000\n"
      }
    }
  }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created import object:

```json
{
  "data": {
    "id": "NqYzgIKvdm",
    "type": "imports",
    "links": { ... },
    "attributes": {
      "resource_type": "tax_categories",
      "format": "csv",
      "parent_resource_id": "daSWQhzjkiZ",
      "status": "pending",
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "inputs": "...",
      "inputs_size": 2,
      "errors_count": 0,
      "warnings_count": 0,
      "destroyed_count": 0,
      "processed_count": 0,
      "errors_log": {},
      "warnings_log": {},
      "cleanup_records": false,
      "attachment_url": nil,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": { ... }
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
To create an import of tax categories for the same **tax calculator**, remember to specify the tax calculator ID as the `parent_resource_id` attribute. On the other hand, specifying the tax\_calculator`_id` attribute for every single item of the `inputs` list lets you import tax categories associated with different tax calculators all at once.
{% endhint %}

For a list of all the required attributes you need to create a tax category, refer to the [related section](/core-api-reference/tax_categories/create) of the API reference.

### Importing more than 10K gift cards using the CLI

{% tabs %}
{% tab title="CLI command" %}
The following command imports a set of gift cards for the market identified by the ID "YlqxGhzDgJ" from a JSON file saved to a specified path:

```
commercelayer imports:create -t gift_cards -p YlqxGhzDgJ -i ./imports/gift_cards.json
```

{% endtab %}

{% tab title="Success message" %}
On success, the CLI prompts this message on your terminal, separating the single imports and showing some basic information about the completed processes:

<pre><code>|     ID     |    Items    |      Import progress      |   %  |    Status   | TBP↓  | Prc.  | Wrn.  | Err.  |
-------------------------------------------------------------------------------------------------------------
| mBxnIErwWO |     1-10000 | █████████████████████████ | 100% | completed   |     0 | 10000 |     0 |     0 | 
| maPBIkDKQQ | 10001-15000 | █████████████████████████ | 100% | completed   |     0 |  5000 |     0 |     0 | 

<strong>Import of 15000 gift cards completed.
</strong></code></pre>

{% endtab %}
{% endtabs %}

## Checking the import status

You can inspect the status of a specific import by fetching the single import by ID and looking at the `status` attribute.

{% tabs %}
{% tab title="Request" %}
The following request fetches a single import, the one identified by the ID "PmjlkIJzRA":

```shell
curl -g -X GET \ 
  'https://yourdomain.commercelayer.io/api/imports/PmjlkIJzRA' \
  -H 'Content-Type: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the single import object:

```json
{
  "data": {
    "id": "PmjlkIJzRA",
    "type": "imports",
    "links": { ... },
    "attributes": {
      "resource_type": "skus",
      "format": "json",
      "parent_resource_id": null,
      "status": "completed",
      "started_at": "2018-01-01T12:00:00.000Z",
      "completed_at": "2018-01-01T12:01:00.000Z",
      "interrupted_at": null,
      "inputs": null,
      "inputs_size": 100,
      "errors_count": 5,
      "warnings_count": 0,
      "destroyed_count": 0,
      "processed_count": 95,
      "errors_log": { ... },
      "warnings_log": {},
      "cleanup_records": "false",
      "attachment_url": "http://cl_imports.s3.amazonaws.com/",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "relationships": {
      "events": { ... }
    },
    "meta": { ... }
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
When you create an import, it tries immediately to start the importing process, entering the `in_progress` status. In case the async queue is saturated, the import remains `pending` until it gets a chance to be processed.
{% endhint %}

{% hint style="warning" %}
If an import gets stuck in the `in_progress` status for any reason, you can mark it as `interrupted` by patching it with the `_interrupt` trigger attribute set to `true`.&#x20;
{% endhint %}

## Webhooks for imports

You can also leverage Commerce Layer real-time webhooks mechanism, listen to `imports.create`, `imports.start`, `imports.complete`, `imports.interrupt`, or `imports.destroy` and react properly.

{% content-ref url="/pages/-LgRXkDyTOVet8bHXwDB" %}
[Real-time webhooks](/core/real-time-webhooks)
{% endcontent-ref %}

## Handling import errors

When an import is completed or interrupted, import errors and warnings (related to [clean-up](#cleaning-up-records)) are reported through the `errors_count`, `errors_log`, `warnings_count`, and `warnings_log` attributes:

```json
...

"errors_count": 5,
"warnings_count": 0,
"destroyed_count": 0,
"processed_count": 95,
"errors_log": {
  "BABYONBU000000E63E7418MX": {
    "name": [
      "has already been taken"
    ]
  },
  "BABYONBU000000E63E7424MX": {
    "shipping_category": [
      "must exist"
    ]
  },
  ...
},
"warnings_log": {},

...
```

{% hint style="info" %}
In case you need to know at which point an import has been interrupted, you can simply sum the `processed_count` and the `errors_count` attributes: the result will be the index of the last `inputs` item that caused the interruption.
{% endhint %}


# Exporting resources

How to bulk export resources and their relationships

Commerce Layer lets you export resources in **JSON** (default) or **CSV** formats. To do that, you need to create a new [export resource](/core-api-reference/exports), specify the `resource_type` you want to export, and the `format` of the exported file. Optionally, you can also specify the relationships you want to [include](#including-associations), apply some [filters](#filtering-exported-data) to narrow the exported data, and decide to [skip](#skipping-redundant-attributes) some redundant attributes.

{% hint style="info" %}
To export a CSV list you need to set the `format` attribute to `csv`. Otherwise, if the format is not specified, your data will be exported using the default format (JSON).
{% endhint %}

The process is **asynchronous** and you can poll the `status` attribute to [check the export progress](#checking-the-export-status). As soon as an export is created you can check the number of items that are going to be exported by inspecting the `records_count` attribute. If you try to export a resource with `records_count = 0`, an error is returned.

{% hint style="info" %}
Resource relationships are exported by default with their IDs, appending the `_id` suffix to the name of the related resource (e.g. `"price_list_id": "xYZkjABcde"`). Some relationships can also be exported as a nested object if specified as valid [included associations](#including-associations).
{% endhint %}

## Attachment URL

Once the export process is completed, the results are compressed ([gzip](https://www.gzip.org/)) and uploaded to an external storage service (currently [Amazon S3](https://aws.amazon.com/s3/)). You can download the exported data using the link exposed in the `attachment_url` attribute.

{% hint style="info" %}
External storage service URLs expire in **5 minutes**. You need to uncompress (`gunzip`) the file in order to read the data back. If the exported data URL is expired you can just [fetch the completed export](#checking-the-export-status) to get a new working one.
{% endhint %}

## Export limits

### Export size

There is **no limit** on export size. However, very large jobs may take several hours to complete, as the data is exported in multiple rounds, prioritizing reliability over speed. You can monitor the current progress of the export by checking the export's `progress` attribute. Once a job round has finished, you can also estimate the completion time by inspecting the `estimated_completion_at` attribute, which is updated after each round.

### Concurrent exports

The maximum number of concurrent exports (i.e. exports whose status is `pending` or `in_progess`) allowed per organization is **10**.

{% hint style="info" %}
If you absolutely need to export any of the [supported resources](#supported-resources) in one go, overriding the API limits above, you can leverage the power of our [CLI export plugin](https://github.com/commercelayer/commercelayer-cli-plugin-exports/) ([see example](#exporting-more-than-10k-orders-using-the-cli)). Alternatively, you can also perform a [search query](/metrics/getting-started/queries/search) using our [Metrics API](https://docs.commercelayer.io/metrics/) (at the moment limited to [orders](/metrics-api-reference/resources/orders), [carts](/metrics-api-reference/resources/carts), and [returns](/metrics-api-reference/resources/returns)).
{% endhint %}

## Supported resources

At the moment, exports are available for almost all of the resources [exposed via API](https://docs.commercelayer.io/core-api-reference/). Please find some examples of how to export them [here below](#examples).

{% hint style="info" %}
With very few exceptions (e.g. shipments, transactions, customer payment sources, etc.), exported outputs (both in JSON or CSV format) can be used as `inputs` for the [imports API](/core/importing-resources). If you're using the *export + import* features to duplicate your dataset records (e.g. to migrate your test data to your live [environment](/core/api-specification#environments)) you may need to [skip](#skipping-redundant-attributes) some redundant attributes. Specifically, if you want to export resources from an organization and import them into a different one, make sure to set the export's `dry_data` attribute to `true` in order to avoid ID conflicts. In that case, we also suggest not to use [fields](#selecting-fields) when exporting the data you plan to re-import elsewhere (use [includes](#including-associations) instead).
{% endhint %}

{% content-ref url="/pages/-M9TjTH488kSdt3AliPK" %}
[Importing resources](/core/importing-resources)
{% endcontent-ref %}

## Including associations

It's possible to include one or more relationships of the exported resource using the `includes` attribute. Relationships will be exported as an object if singular (`has_one` or `belongs_to`), or as an array of objects if multiple (`has_many`) — check Commerce Layer API [data model](https://commercelayer.io/docs/data-model/) for more information on how resources relate to each other.

{% hint style="warning" %}
If you use the CSV format to export your data the output will have the relationship attributes **flattened** together with the parent resource ones. As a result, you'll find the resource attributes repeated on multiple lines, with relationship ones appended at the end. When exporting tags together with a tagged resource the cells belonging to the `tags.id` and `tags.name` columns contain a string with the list of IDs/names, comma separated. In general, using CSV is fine for simple exports (resources with a few attributes and no relationship included), otherwise we strongly recommend using JSON.
{% endhint %}

When including associations, multiple levels of relationships are supported. You just need to append the more specific using the use the [dot notation](https://idratherbewriting.com/learnapidoc/docapis_diving_into_dot_notation.html) `.` (e.g. [line item options for orders](#exporting-a-list-of-orders), or [price tiers for SKUs](#exporting-a-filtered-list-of-skus-with-prices-price-tiers-stock-items-and-tax-categories-json)).

{% hint style="warning" %}
CSV `format` supports only **one level** of relationship (e.g. if you try to include `line_items.line_item_options` when exporting orders, only the line items will be exported).
{% endhint %}

### Supported associations

All of the valid resource relationships can be included when exporting. Please refer to the specific resource page in the [Core API reference](https://docs.commercelayer.io/core-api-reference/) to check which relationships you can include when exporting it.

{% hint style="warning" %}
In case you specify an invalid include for the exported resource, an error is raised before creating (and starting) the export.&#x20;
{% endhint %}

## Selecting fields

When exporting resources, you can select the resource fields to be exported in advance by specifying the `fields` attribute as an array of values.

For the main exported resource you can pass fields using the plain attribute names. For any related association's attribute use the [dot notation](https://idratherbewriting.com/learnapidoc/docapis_diving_into_dot_notation.html) (the same used when [including associations](#including-associations)), i.e. `.` followed by the field name.&#x20;

{% hint style="info" %}
If you want to export all the fields of a resource, use the asterisk `*` (works both for the main and related resources).
{% endhint %}

For example, if you want to export SKUs with their code and name plus some specific fields of the associated prices and stock items and all the fields of the associated shipping category, use a `field` array like this:

```json
...
  "fields": [
    "code",
    "name",
    "prices.amount_cents",
    "prices.price_list.name",
    "stock_items.stock_location.code",
    "shipping_category.*"
    ...
  ]
```

{% hint style="warning" %}
Some attributes which are potentially sensible (e.g. any kind of credentials) will not be included in the exported file also if you explicitly specify them in the `fields` array.
{% endhint %}

### Fields vs. includes

Specifying `includes` is completely redundant when using `fields` since any association's related attribute listed among the fields automatically includes the related resource. This also means that:

* &#x20;If you specify a field using an invalid related association, an error is raised before creating (and starting) the export.
* If you include an association that has no corresponding related field, its data will not be exported.

{% hint style="info" %}
As a general rule of thumb, use `includes` when you want to export all the fields of the included resource and use `fields` when you want to export specific fields of the resource only.
{% endhint %}

## Filtering exported data

When exporting resources, you can fine-tune the data to be exported by applying some filters (both to the resources and their relationships) using the `filters` attribute:

```json
...
  "filters": {
    "{{predicate}}": {{value}},
    ...
  }
```

To compose the filter predicate you just need to follow the [same syntax](/core/filtering-data) you use when filtering a collection of resources — `{{attributes}}_{{matcher}}`. You must specify filtering rules as a valid JSON object. List values for the `*_in` matcher need to be expressed as arrays (as in [this example](#exporting-a-filtered-list-of-bundles-with-sku-lists-and-sku-list-items-csv)).

{% content-ref url="/pages/-LgSr9xsTDp7-qgaFMo6" %}
[Filtering data](/core/filtering-data)
{% endcontent-ref %}

## Skipping redundant attributes

You might want to compact exported data by removing some redundant attributes from the final JSON or CSV output. To do that, set the `dry_data` specific boolean attribute to `true` — the following attributes and values will be skipped:

* The main resource IDs.
* The timestamp attributes (`created_at` and `updated_at`).
* Any empty or `null` attribute value (working when exporting in the JSON format only).
* All the formatted amounts other than cents (e.g. for prices, orders, etc.).

## Interrupting and restarting

You can interrupt an in-progress export at any time by updating it with the `_interrupt` trigger attribute. The export will stop at the end of the current round, recording the last resource processed and preserving information about the remaining data.

To restart an interrupted export, update it passing the `_start` trigger attribute. Processing will resume from the point of interruption, and the `estimated_completion_at` attribute will be recalculated based on the time of the restart.

{% hint style="warning" %}
The resources to be exported are automatically capped at the timestamp when the export was created. This ensures consistency by preventing the dataset from growing in size or simply changing during the process (e.g. if a new import begins while the export is still running).
{% endhint %}

## Examples

### Exporting some fields of a filtered list of addresses (JSON)

{% tabs %}
{% tab title="Request" %}
The following request creates an export of a list of addresses in `JSON` format, filtered by country code and city, fetching just the `full_name` and `full_address` fields:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/exports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
	"data": {
	  "type": "exports",
	  "attributes": {
	    "resource_type": "addresses",
	    "fields": [ "full_name", "full_address" ],
	    "filters": {
	      "country_code_eq": "IT",
	      "city_in": [ "Rome", "Milan", "Prato" ]
	    }
	  }
	}
      }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created export object:

```json
{
  "data": {
    "id": "PmjlkIJzRA",
    "type": "exports",
    "links": {...},
    "attributes": {
      "resource_type": "addresses",
      "format": "json",
      "status": "pending",
      "includes": [],
      "fields": ["full_name", "full_address"],
      "filters": {"country_code_eq": "IT", "city_in": ["Rome", "Milan", "Prato"]},
      "dry_data": true,
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "records_count": 8765,
      "attachment_url": null,
      "errors_log": {},
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": {...}
  }
}
```

{% endtab %}
{% endtabs %}

### Exporting a filtered list of bundles with SKU lists and SKU list items (CSV)

{% tabs %}
{% tab title="Request" %}
The following request creates an export of a list of bundles and their associated SKU lists and SKU list items in CSV format, filtered by SKU list name:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/exports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
	"data": {
	  "type": "exports",
	  "attributes": {
	    "resource_type": "bundles",
	    "format": "csv",
	    "includes": [ "sku_list", "sku_list_items" ],
	    "filters": {
	      "sku_list_name_in": [ "6 pack", "12 pack" ]
	    }
	  }
	}
      }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created export object:

```json
{
  "data": {
    "id": "PmjlkIJzRA",
    "type": "exports",
    "links": {...},
    "attributes": {
      "resource_type": "bundles",
      "format": "csv",
      "status": "in_progress",
      "includes": ["sku_list", "sku_list_items"],
      "fields": [],
      "filters": {"sku_list_name_in": ["six pack", "12 pack"]},
      "dry_data": null,
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "records_count": 43,
      "attachment_url": null,
      "errors_log": {},
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": {...}
  }
}
```

{% endtab %}
{% endtabs %}

### Exporting a list of coupons (JSON)

{% tabs %}
{% tab title="Request" %}
The following request creates an export of a list of coupons in JSON format, skipping the redundant attributes:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/exports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
	"data": {
	  "type": "exports",
	  "attributes": {
	    "resource_type": "coupons",
	    "dry_data": true
	  }
	}
      }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created export object:

```json
{
  "data": {
    "id": "PmjlkIJzRA",
    "type": "exports",
    "links": {...},
    "attributes": {
      "resource_type": "coupons",
      "format": "json",
      "status": "in_progress",
      "includes": [],
      "fields": [],
      "filters": {},
      "dry_data": true,
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "records_count": 9876,
      "attachment_url": null,
      "errors_log": {},
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": {...}
  }
}
```

{% endtab %}
{% endtabs %}

### Exporting some fields a filtered list of customer addresses with addresses and customers (JSON)

{% tabs %}
{% tab title="Request" %}
The following request creates an export of a list of customer addresses in JSON format, filtered by customer's email, fetching just the associated customer `email` and address `full_address` fields:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/exports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
	"data": {
	  "type": "exports",
	  "attributes": {
	    "resource_type": "customer_addresses",
	    "format": "json",
	    "fields": [ "address.full_address", "customer.email" ],
	    "filters": {
	      "customer_email_end": ".com"
	    }
	  }
	}
      }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created export object:

```json
{
  "data": {
    "id": "PmjlkIJzRA",
    "type": "exports",
    "links": {...},
    "attributes": {
      "resource_type": "customer_addresses",
      "format": "json",
      "status": "in_progress",
      "includes": ["address", "customer"],
      "fields": ["address.full_address", "customer.email"],
      "filters": {"customer_email_end": ".com"},
      "dry_data": true,
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "records_count": 254,
      "attachment_url": null,
      "errors_log": {},
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": {...}
  }
}
```

{% endtab %}
{% endtabs %}

### Exporting a filtered list of customer subscriptions with customers (CSV)

{% tabs %}
{% tab title="Request" %}
The following request creates an export of a list of customer subscriptions and their associated customers in CSV format filtered by email:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/exports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
	"data": {
	  "type": "exports",
	  "attributes": {
	    "resource_type": "customer_subscriptions",
	    "format": "csv",
	    "includes": [ "customer" ],
	    "filters": {
	      "customer_email_matches": "%gmail.com"
	    }
	  }
	}
      }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created export object:

```json
{
  "data": {
    "id": "PmjlkIJzRA",
    "type": "exports",
    "links": {...},
    "attributes": {
      "resource_type": "customer_subscriptions",
      "format": "csv",
      "status": "in_progress",
      "includes": ["customer"],
      "fields": [],
      "filters": {"customer_email_matches": "%gmail.com"},
      "dry_data": null,
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "records_count": 345,
      "attachment_url": null,
      "errors_log": {},
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": {...}
  }
}
```

{% endtab %}
{% endtabs %}

### Exporting some fields of a filtered list of customers with customer subscriptions (JSON)

{% tabs %}
{% tab title="Request" %}
The following request creates an export of a list of customers in JSON format filtered by email, fetching all the customer attributes and just the customer subscription `reference` field:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/exports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
	"data": {
	  "type": "exports",
	  "attributes": {
	    "resource_type": "customers",
	    "format": "json",
	    "fields": [ "*", "customer_subscriptions.reference" ],
	    "filters": {
	      "email_end": ".com"
	    }
	  }
	}
      }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created export object:

```json
{
  "data": {
    "id": "PmjlkIJzRA",
    "type": "exports",
    "links": {...},
    "attributes": {
      "resource_type": "customers",
      "format": "json",
      "status": "in_progress",
      "includes": ["customer_subscriptions"],
      "fields": ["*", "customer_subscriptions.reference"],
      "filters": {"email_end": ".com"},
      "dry_data": true,
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "records_count": 254,
      "attachment_url": null,
      "errors_log": {},
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": {...}
  }
}
```

{% endtab %}
{% endtabs %}

### Exporting a filtered list of gift cards (CSV)

{% tabs %}
{% tab title="Request" %}
The following request creates an export of a list of gift cards in CSV format, filtered by the date and time at which they were created:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/exports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
	"data": {
	  "type": "exports",
	  "attributes": {
	    "resource_type": "gift_cards",
	    "format": "csv",
	    "filters": {
	      "created_at_gteq": "2018-01-01T12:00:00.000Z"
	    }
	  }
	}
      }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created export object:

```json
{
  "data": {
    "id": "PmjlkIJzRA",
    "type": "exports",
    "links": {...},
    "attributes": {
      "resource_type": "gift_cards",
      "format": "csv",
      "status": "in_progress",
      "includes": [],
      "fields": [],
      "filters": {"created_at_gteq": "2018-01-01T12:00:00.000Z"},
      "dry_data": null,
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "records_count": 349,
      "attachment_url": null,
      "errors_log": {},
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": {...}
  }
}
```

{% endtab %}
{% endtabs %}

### Exporting a filtered list of orders with customer, addresses, line items, line item options, payment method, and refunds (JSON) <a href="#exporting-a-list-of-orders" id="exporting-a-list-of-orders"></a>

{% tabs %}
{% tab title="Request" %}
The following request creates an export of a list of orders dry data with the associated customer, addresses, line items, line item options, payment method, and refunds in JSON format, filtered by status, country code, and the date and time at which they were placed:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/exports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
	"data": {
	  "type": "exports",
	  "attributes": {
	    "resource_type": "orders",
	    "includes": [
	      "customer",
	      "shipping_address",
	      "billing_address",
	      "line_items.line_item_options",
	      "payment_method",
	      "refunds"
	    ],
	    "filters": {
	      "status_in": [ "placed", "approved" ],
	      "placed_at_gteq": "2018-01-01T12:00:00.000Z",
	      "country_code_eq": "IT"
	    },
	    "dry_data": true
	  }
	}
      }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created export object:

```json
{
  "data": {
    "id": "PmjlkIJzRA",
    "type": "exports",
    "links": {...},
    "attributes": {
      "resource_type": "orders",
      "format": "json",
      "status": "in_progress",
      "includes": ["customer", "shipping_address", "billing_address", "line_items.line_item_options", "payment_method", "refunds"],
      "fields": [],
      "filters": {"status_in": ["placed", "approved"], "placed_at_gteq": "2018-01-01T12:00:00.000Z", "country_code_eq": "IT"},
      "dry_data": true,
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "records_count": 6499,
      "attachment_url": null,
      "errors_log": {},
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": {...}
  }
}
```

{% endtab %}
{% endtabs %}

### Exporting a filtered list of order subscriptions with order subscription items and customer payment source (JSON)

{% tabs %}
{% tab title="Request" %}
The following request creates an export of a list of order subscriptions with the associated order subscription items and customer payment source in JSON format (skipping the redundant attributes), filtered by customer email:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/exports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
	"data": {
	  "type": "exports",
	  "attributes": {
	    "resource_type": "order_subscriptions",
	    "format": "json",
	    "includes": [ "order_subscription_items", "customer_payment_source" ],
	    "filters": {
	      "customer_email_eq": "george@gmail.com"
	    },
	    "dry_data": true
	  }
	}
      }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created export object:

```json
{
  "data": {
    "id": "PmjlkIJzRA",
    "type": "exports",
    "links": {...},
    "attributes": {
      "resource_type": "order_subscriptions",
      "format": "json",
      "status": "in_progress",
      "includes": ["order_subscription_items", "customer_payment_source"],
      "fields": [],
      "filters": {"customer_email_eq": "george@gmail.com"},
      "dry_data": true,
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "records_count": 254,
      "attachment_url": null,
      "errors_log": {},
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": {...}
  }
}
```

{% endtab %}
{% endtabs %}

### Exporting some fields of a filtered list of prices with price tiers (CSV)

{% tabs %}
{% tab title="Request" %}
The following request creates an export of a list of prices with associated SKUs and price tiers in CSV format, fetching just the price's `amount_cents` and the associated SKU's `code`, price tier's `type` and `price_amount_cents` fields, filtered by the associated price list's currency code:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/exports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
	"data": {
	  "type": "exports",
	  "attributes": {
	    "resource_type": "prices",
	    "format": "csv",
	    "fields": [ "amount_cents", "sku.code", "price_tiers.type", "price_tiers.price_amount_cents" ],
	    "filters": {
	      "price_list_currency_code_eq": "USD"
	    },
	    "dry_data": true
	  }
	}
      }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created export object:

```json
{
  "data": {
    "id": "PmjlkIJzRA",
    "type": "exports",
    "links": {...},
    "attributes": {
      "resource_type": "prices",
      "format": "csv",
      "status": "in_progress",
      "includes": ["sku", "price_tiers"],
      "fields": ["amount_cents", "sku.code", "price_tiers.type", "price_tiers.price_amount_cents"],
      "filters": {"price_list_currency_code_eq": "USD"},
      "dry_data": true,
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "records_count": 3456,
      "attachment_url": null,
      "errors_log": {},
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": {...}
  }
}
```

{% endtab %}
{% endtabs %}

### Exporting a filtered list of SKU lists with SKU list items (JSON)

{% tabs %}
{% tab title="Request" %}
The following request creates an export of a list of SKU lists with associated SKU list items in JSON format, filtered SKU list type (manual):

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/exports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
	"data": {
	  "type": "exports",
	  "attributes": {
	    "resource_type": "sku_lists",
	    "includes": [ "sku_list_items" ],
	    "filters": {
	      "manual_true": true
	    }
	  }
	}
      }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created export object:

```json
{
  "data": {
    "id": "PmjlkIJzRA",
    "type": "exports",
    "links": {...},
    "attributes": {
      "resource_type": "sku_lists",
      "format": "json",
      "status": "in_progress",
      "includes": ["sku_list_items"],
      "fields": [],
      "filters": {"manual_true": true},
      "dry_data": null,
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "records_count": 3456,
      "attachment_url": null,
      "errors_log": {},
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": {...}
  }
}
```

{% endtab %}
{% endtabs %}

### Exporting a filtered list of SKUs with prices, price tiers, stock items, and tax categories (JSON)

{% tabs %}
{% tab title="Request" %}
The following request creates an export with a list of SKUs, with the associated prices, price tiers, stock items, and tax categories in JSON format (skipping the redundant attributes), filtered by SKU name:

<pre class="language-shell"><code class="lang-shell"><strong>curl -g -X POST \
</strong>  'https://yourdomain.commercelayer.io/api/exports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
	"data": {
	  "type": "exports",
	  "attributes": {
	    "resource_type": "skus",
	    "includes": [ "prices.price_tiers", "stock_items", "tax_categories" ],
	    "filters": {
	      "name_cont": "FW"
	    },
	    "dry_data": true
	  }
	}
      }'
</code></pre>

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created export object:

```json
{
  "data": {
    "id": "PmjlkIJzRA",
    "type": "exports",
    "links": {...},
    "attributes": {
      "resource_type": "skus",
      "format": "json",
      "status": "in_progress",
      "includes": [ "prices.price_tiers", "stock_items", "tax_categories" ],
      "fields": [],
      "filters": { "name_cont": "FW" },
      "dry_data": true,
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "records_count": 2345,
      "attachment_url": null,
      "errors_log": {},
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": {...}
  }
}
```

{% endtab %}
{% endtabs %}

### Exporting some fields of a filtered list of stock items with SKUs and stock location (CSV)

{% tabs %}
{% tab title="Request" %}
The following request creates an export of a list of stock items and the associated SKUs and stock location in CSV format (skipping the redundant attributes), filtered by stock item quantity, fetching just the stock item's `quantity`,  and the associated SKU's `code` and stock location's `name` fields:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/exports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
	"data": {
	  "type": "exports",
	  "attributes": {
	    "resource_type": "stock_items",
	    "format": "csv",
	    "fields": [ "quantity", "sku.code", "stock_location.name" ],
	    "filters": {
	      "quantity_gteq": 1
	    },
	    "dry_data": true
	  }
	}
      }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created export object:

```json
{
  "data": {
    "id": "PmjlkIJzRA",
    "type": "exports",
    "links": {...},
    "attributes": {
      "resource_type": "stock_items",
      "format": "csv",
      "status": "in_progress",
      "includes": ["sku", "stock_location"],
      "fields": ["quantity", "sku.code", stock_location.name],
      "filters": {"quantity_gteq": 1},
      "dry_data": true,
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "records_count": 4567,
      "attachment_url": null,
      "errors_log": {},
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": {...}
  }
}
```

{% endtab %}
{% endtabs %}

### Exporting some fields of a filtered list of stock transfers with SKUs and stock locations (CSV)

{% tabs %}
{% tab title="Request" %}
The following request creates an export of a list of stock transfers (filtered by their quantity) with the associated stock locations and SKUs in CSV format (skipping the redundant attributes), fetching just the stock transfer's `quantity`, the origin and destination stock location `name`, and all the SKU's fields:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/exports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
	"data": {
	  "type": "exports",
	  "attributes": {
	    "resource_type": "stock_transfers",
	    "format": "csv",
	    "fields": [ "quantity", "sku.*", "origin_stock_location.name, "destination_stock_location.name" ],
	    "filters": {
	      "quantity_gteq": 1
	    },
	    "dry_data": true
	  }
	}
      }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created export object:

```json
{
  "data": {
    "id": "PmjlkIJzRA",
    "type": "exports",
    "links": {...},
    "attributes": {
      "resource_type": "stock_transfers",
      "format": "csv",
      "status": "in_progress",
      "includes": ["sku", "origin_stock_location", "destination_stock_location"],
      "fields": ["quantity", "sku.*", "origin_stock_location.name, "destination_stock_location.name"],
      "filters": {"quantity_gteq": 1},
      "dry_data": true,
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "records_count": 4567,
      "attachment_url": null,
      "errors_log": {},
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": {...}
  }
}
```

{% endtab %}
{% endtabs %}

### Exporting all the tags (CSV)

{% tabs %}
{% tab title="Request" %}
The following request creates an export of all the tags you created for your organization in CSV format:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/exports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
	"data": {
          "type": "exports",
          "attributes": {
            "resource_type": "tags",
            "format": "csv"
          }
        }
      }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created export object:

```json
{
  "data": {
    "id": "WoDOghDQlz",
    "type": "exports",
    "links": { ... },
    "attributes": {
      "resource_type": "tags",
      "format": "csv",
      "status": "in_progress",
      "includes": [],
      "fields": [],
      "filters": {},
      "dry_data": null,
      "started_at": "2018-01-01T12:00:00.000Z",
      "completed_at": null,
      "interrupted_at": null,
      "records_count": 123,
      "attachment_url": null,
      "errors_log": {},
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "relationships": { ... },
    "meta": { ... }
  }
}
```

{% endtab %}
{% endtabs %}

### Exporting some fields of all the SKUs tagged with at least one of two tags (JSON)

{% tabs %}
{% tab title="Request" %}
The following request creates an export of all the SKU associated with the tag identified by the "geJmexflJQ" ID or by the "XEqZPxfPam" ID, fetching just the `code` and tag `name` fields, in JSON format:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/exports' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
	"data": {
          "type": "exports",
          "attributes": {
            "resource_type": "skus",
            "fields": [ "code", "tags.name" ],
            "filters": {
              "tags_id_in": [ "geJmexflJQ", "XEqZPxfPam" ]
            }
          }
        }
      }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created export object:

```json
{
  "data": {
    "id": "wlyGbhDNjM",
    "type": "exports",
    "links": { ... },
    "attributes": {
      "resource_type": "skus",
      "format": "json",
      "status": "in_progress",
      "includes": ["tags"],
      "fields": ["code", "tags.name"],
      "filters": {
        "tags_id_in": ["geJmexflJQ", "XEqZPxfPam"]
      },
      "dry_data": null,
      "started_at": "2018-01-01T12:00:00.473Z",
      "completed_at": null,
      "interrupted_at": null,
      "records_count": 234,
      "attachment_url": null,
      "errors_log": {},
      "created_at": "2018-01-01T12:00:00.463Z",
      "updated_at": "2018-01-01T12:00:00.472Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "relationships": { ... },
    "meta": { ... }
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
When filtering a list of tagged resources by tag(s) the only allowed predicates are `tags_id_in` and `tags_id_not_in`.
{% endhint %}

### Exporting more than 10K orders using the CLI

{% tabs %}
{% tab title="CLI command" %}
The following command exports all the approved orders whose amount is over $1000 (including the associated customer, line items, and tags) in JSON format into a single file and saves it to a specified path:

```
commercelayer exports:all -t orders -i customer,line_items,tags -w status_eq=approved -w currency_code_eq=USD -w total_amount_cents_gt=100000 -X ./exports/orders
```

{% endtab %}

{% tab title="Success message" %}
On success, the CLI prompts this message on your terminal, separating the single exports and showing some basic information about the completed processes:

<pre><code>Exporting 15000 orders ...
✓ Export 1 completed
✓ Export 2 completed

<strong>Export of 15000 orders completed.
</strong>
Exported file saved to ./exports/orders.json
</code></pre>

{% endtab %}
{% endtabs %}

## Checking the export status

You can inspect the status of a specific export by fetching the single export by ID and looking at the `status` attribute.

{% tabs %}
{% tab title="Request" %}

```shell
curl -g -X GET \ 
  'https://yourdomain.commercelayer.io/api/exports/PmjlkIJzRA' \
  -H 'Content-Type: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the single export object:

```json
{
  "data": {
    "id": "PmjlkIJzRA",
    "type": "exports",
    "links": {...},
    "attributes": {
      "resource_type": "stock_items",
      "format": "csv",
      "status": "completed",
      "includes": ["sku"],
      "fields": [],
      "filters": {"quantity_gteq": 1},
      "dry_data": true,
      "started_at": "2018-01-01T12:00:00.000Z",
      "completed_at": "2018-01-01T12:03:00.000Z",
      "interrupted_at": null,
      "records_count": 4567,
      "attachment_url": "http://cl_exports.s3.amazonaws.com/",
      "errors_log": {},
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "meta": {...}
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
When you create an export, it tries immediately to start the exporting process, entering the `in_progress` status. In case the async queue is saturated, the export remains `pending` until it gets a chance to be processed.
{% endhint %}

{% hint style="warning" %}
If an export gets stuck in the `in_progress` status for any reason, you can mark it as `interrupted` by patching it with the `_interrupt` trigger attribute set to `true`. In case an export fails instead, it is automatically moved to the `interrupted` status and the `errors_log` attribute gets filled with the runtime error that caused the interruption.&#x20;
{% endhint %}

## Webhooks for exports

You can also leverage Commerce Layer real-time webhooks mechanism, listen to `exports.create`, `exports.start`, `exports.complete`, `exports.interrupt`, or `exports.destroy` and react properly.

{% content-ref url="/pages/-LgRXkDyTOVet8bHXwDB" %}
[Real-time webhooks](/core/real-time-webhooks)
{% endcontent-ref %}


# Cleaning up resources

How to bulk remove resources and their relationships

Commerce Layer lets you remove resources and their associated relationships in batches. To do that, you need to create a new [cleanup](/core-api-reference/cleanups) resource and specify the `resource_type` you want to remove. Optionally, you can also apply some [filters](#filtering-the-data-to-be-removed) to narrow the affected data.

The process is **asynchronous** and you can poll the `status` attribute to check the clean-up progress. Once the operation has been completed you can check the number of removed items by inspecting the `processed_count` attribute. In case of [validation errors](#handling-cleanup-errors), the `errors_count` and `errors_log` attributes are populated.

{% hint style="danger" %}
Since it is fired in the background as soon as the cleanup resource is created, **the removal process** i**s not reversible**: all of the resources matching the filters criteria and their associated relationships will be removed in bulk. We suggest that you create a backup of the resources you're going to clean up [exporting](/core/exporting-resources) them first (making sure to use the same [filters](/core/exporting-resources#filtering-exported-data) and [include](/core/exporting-resources#including-associations) all of the affected relationships).
{% endhint %}

### Cleanup limits

#### Maximum cleanup size

There is no limit on the total number of resources you can clean up, but the single batches are subject to some soft limits: the `records_count` must be a maximum of **10000** records, otherwise the cleanup will be rejected at the time of creation.

#### Maximum error percentage

During the clean-up process, the errors count is also monitored: cleanups whose `errors_count` attribute value overflows the maximum percentage of **10%** of the total `records_count` will be interrupted.

#### Concurrent cleanups

The maximum number of concurrent cleanups (i.e. cleanups whose status is `pending` or `in_progess`) allowed per organization is **10**.

{% hint style="info" %}
If you absolutely need to clean up any of the [supported resources](#supported-resources) in one go, overriding the maximum cleanup size and concurrent cleanup API limits above, you can leverage the power of our [CLI cleanups plugin](https://github.com/commercelayer/commercelayer-cli-plugin-cleanups/) ([see example](#cleaning-up-more-than-10k-skus-using-the-cli)).&#x20;
{% endhint %}

### Supported resources

At moment, you can clean up the following resources and associated relationships (more to come):

* **Bundles**
* **Gift cards**
* **Prices** > price tiers
* **Promotions** > promotion rules
* **SKU lists** > SKU list items, bundles
* **SKU options** > line item options
* **SKUs** > in-stock subscriptions, prices, SKU list items, stock items, tax categories
* **Stock items**

Please find some examples of how to clean up them [here below](#examples).

{% hint style="info" %}
Please note that associated relationships will be **automatically removed** along with the parent resource. The clean-up process works in cascade (e.g. removing a promotion will also remove its associated promotion rules and all the related coupons).
{% endhint %}

### Constraints

In order to preserve data integrity the cleanups are subject to some relationship constraints. If such constraints are violated an error is added to the `errors_log` and the `errors_count` is incremented (resulting in an interruption if the [10% threshold](#maximum-error-percentage) is exceeded):

* **SKU lists** — must not be linked to any promotion or promotion rules (i.e. any associated promotion must be removed first)
* **SKUs** — must not be linked to any SKU list item within a bundle (i.e. any associated bundle must be removed first)

### Filtering the data to be removed

When cleaning up resources, you can fine-tune the data to be removed by applying some filters (both to the resources and their relationships) using the `filters` attribute:

```
...
  "filters": {
    "{{predicate}}": {{value}},
    ...
  }
```

To compose the filter predicate you just need to follow the [same syntax](/core/filtering-data) you use when filtering a collection of resources — `{{attributes}}_{{matcher}}`. You must specify filtering rules as a valid JSON object. List values for the `*_in` matcher need to be expressed as arrays.

{% hint style="warning" %}
When specifying `filters` as a JSON attribute, the syntax of  the `*_jcont` predicate changes. You must specify the value of the predicate as a plain string:&#x20;

`{ "metadata_jcont": \"{"key": "value"}\" }`
{% endhint %}

{% content-ref url="/pages/-LgSr9xsTDp7-qgaFMo6" %}
[Filtering data](/core/filtering-data)
{% endcontent-ref %}

### Examples

#### Cleaning up  a batch of SKUs <a href="#importing-a-list-of-addresses-csv" id="importing-a-list-of-addresses-csv"></a>

{% tabs %}
{% tab title="Request" %}
The following request creates a cleanup to remove the SKUs matching the specified code, along with their relationships:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/cleanups' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
	"data": {
	  "type": "cleanups",
	  "attributes": {
	    "resource_type": "skus",
            "filters": {
	      "code_start": "SHIRT"
	    }
	  }
	}
      }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created cleanup object:

```json
{
  "data": {
    "id": "WmjloIJzAS",
    "type": "cleanups",
    "links": {...},
    "attributes": {
      "resource_type": "skus",
      "status": "pending",
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "filters": {"code_start": "SHIRT"},
      "records_count": 100,
      "errors_count": 0,
      "processed_count": 0,
      "errors_log": {...},
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "relationships": {
      "events": { ... }
    },
    "meta": {...}
  }
}
```

{% endtab %}
{% endtabs %}

#### Cleaning up a batch of promotions

{% tabs %}
{% tab title="Request" %}
The following request creates a cleanup to remove all the promotions that expired after a specified date, along with their relationships:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/cleanups' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
	"data": {
	  "type": "cleanups",
	  "attributes": {
	    "resource_type": "promotions",
	    "filters": {
	      "expired_at_gteq": "2018-01-01T12:00:00.000Z"
	    }
	  }
	}
      }'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created import object:

```json
{
  "data": {
    "id": "HGfdRsErUk",
    "type": "cleanups",
    "links": {...},
    "attributes": {
      "resource_type": "promotions",
      "status": "pending",
      "started_at": null,
      "completed_at": null,
      "interrupted_at": null,
      "filters": {"expired_at_gteq": "2018-01-01T12:00:00.000Z"},
      "records_count": 55,
      "errors_count": 0,
      "processed_count": 0,
      "errors_log": {...},
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "relationships": {
      "events": { ... }
    },
    "meta": {...}
  }
}
```

{% endtab %}
{% endtabs %}

#### Cleaning up more than 10K SKUs using the CLI

{% tabs %}
{% tab title="CLI command" %}
The following command cleans up all the SKUs whose code contains a specific subset of characters:

```
commercelayer cleanups:create -t skus -w code_cont=FLASHSALE
```

{% endtab %}

{% tab title="Success message" %}
On success, the CLI prompts this message on your terminal, separating the single cleanups and showing some basic information about the completed processes:

<pre><code>|     ID     |     Cleanup progress      |   %  |    Status   | TBP↓  | Prc.  | Err.  |
---------------------------------------------------------------------------------------
| DRlYbHDopv | █████████████████████████ | 100% | completed   |     0 | 10000 |     0 | 
| MReZgHXLpw | █████████████████████████ | 100% | completed   |     0 |  5000 |     0 | 

<strong>Cleanup of 15000 skus completed.
</strong></code></pre>

{% endtab %}
{% endtabs %}

### Checking the cleanup status

You can inspect the status of a specific cleanup by fetching it by ID and looking at the `status` attribute.

{% tabs %}
{% tab title="Request" %}
The following request fetches a single cleanup, the one identified by the ID "WmjloIJzAS":

```shell
curl -g -X GET \ 
  'https://yourdomain.commercelayer.io/api/cleanups/WmjloIJzAS' \
  -H 'Content-Type: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the single cleanup object:

```json
{
  "data": {
    "id": "WmjloIJzAS",
    "type": "cleanups",
    "links": {...},
    "attributes": {
      "resource_type": "skus",
      "status": "completed",
      "started_at": "2018-01-01T12:00:00.000Z",
      "completed_at": "2018-01-01T12:01:00.000Z",
      "interrupted_at": null,
      "filters": {},
      "records_count": 100,
      "errors_count": 1,
      "processed_count": 99,
      "errors_log": {...},
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": null,
      "reference_origin": null,
      "metadata": {}
    },
    "relationships": {
      "events": { ... }
    },
    "meta": {...}
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
When you create a cleanup, it tries immediately to start the removal process, entering the `in_progress` status. In case the async queue is saturated, the cleanup remains `pending`  until it gets a chance to be processed.
{% endhint %}

{% hint style="warning" %}
If a cleanup gets stuck in the `in_progress` status for any reason, you can mark it as `interrupted` by patching it with the `_interrupt` trigger attribute set to `true`.&#x20;
{% endhint %}

### Webhooks for cleanups

You can also leverage Commerce Layer real-time webhooks mechanism, listen to `cleanups.create`, `cleanups.start`, `cleanups.complete`, `cleanups.interrupt`, or `cleanups.destroy` and react properly.

{% content-ref url="/pages/-LgRXkDyTOVet8bHXwDB" %}
[Real-time webhooks](/core/real-time-webhooks)
{% endcontent-ref %}

### Handling cleanup errors

When a cleanup is completed or interrupted, [constraints](#constraints) errors are reported through the `errors_count` and `errors_log` attributes:

```json
...

"errors_count": 5,
"processed_count": 95,
"errors_log": {
  "HjKhdjGfDD": "Cannot delete record because of dependent bundles",
  ...
},

...
```


# External resources

How to manage resources via external serverless functions

Commerce Layer lets you manage some resources (i.e. prices, promotions, payment gateways, tax calculators, and more to come) from the outside of the platform itself, using an external service of your choice or a serverless function.

In order to get the data from the external source, when needed, we trigger a `POST` request to the endpoint that you specified. The request contains a JSON payload that will be detailed case by case, along with the successful response (or error) format we expect to receive back.

When you create a new external resource, a **shared secret** is generated. It will be used each time we send data to the specified endpoint to sign the payload. The signature will be stored in the **X-CommerceLayer-Signature** [header](#request-headers) so that you can verify the callback authenticity and consider it reliable.

{% content-ref url="/pages/-MIOPl2nMJoIW7dGQnpO" %}
[Callbacks security](/core/callbacks-security)
{% endcontent-ref %}

## Circuit breaker

All the external resources are subject to a circuit breaker check: if the call to your external endpoint fails consecutively more than **30** times, the circuit breaker opens and any further request to the resource will be skipped.

{% hint style="warning" %}
An open circuit for an external resource might result in a `422` error in some specific cases (e.g. [external prices](/core/external-resources/external-prices)), but it is usually ignored with a `200 OK` response status to avoid accidental side effects on the order lifecycle.
{% endhint %}

### Resetting the circuit

The circuit is automatically reset anytime a call to your external endpoint succeeds before reaching the counter's threshold.

You can also reset the circuit manually by passing the `_reset_circuit` trigger attribute (you must use [integration](/core/api-credentials#integration) API credentials). This is also your only option in case the circuit is stuck in the open state:

```shell
curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/external_gateways/bGHfCxZJKl' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "external_gateways",
      "id": "bGHfCxZJKl",
      "attributes": {
        "_reset_circuit": true
      }
    }
  }'
```

{% hint style="info" %}
You'll be notified via email every time the circuit breaker counter reaches **10** consecutive failures, as an early warning. Another notification is sent when the circuit breaker opens.
{% endhint %}

## Payload format

The request payload sent to an external endpoint has the same format that you get when fetching a resource through the REST API, with some relevant resources included.

```json
  "data": {
    "id": "resource-id",
    "type": "resource-type",
    "links": { ... },
    "attributes": {...},
    "relationships": { ... },
    "meta": { ... }
  },
  "included": [
    {
      "id": "included-resource-id",
      "type": "included-resource-type",
      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    { ... }
  ]
}
```

## Custom include list

As you can see from the [sample payload](#payload-format) above, some relationships are included by default in the request payload (please refer to the specific resource for the complete list). If you need to specify a custom list of relationships that will be included in the payload, you can **overwrite the default list** by passing it into the `external_includes` attribute of the related external resource at creation or update time (here below an example related to the creation of an [external tax calculator](/core/external-resources/external-tax-calculators) with a custom include list):&#x20;

<pre class="language-bash"><code class="lang-bash">curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/external_tax_calculators' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "external_tax_calculators",
      "attributes": {
        "name": "My tax calculator",
        "tax_calculator_url": "https://external_calculator.yourbrand.com",
<strong>        "external_includes": [ "line_items", "line_item_options", "line_items.item" ]
</strong>      }
    }
  }'
</code></pre>

{% hint style="info" %}

#### Allowed includes based on the target resource

When specifying custom included resources, always reference the target resource required by the external request:

* The **order** for [external promotions](/core/external-resources/external-promotions#request) and [external tax calculators](/core/external-resources/external-tax-calculators#request).
* The **shipment** for [external shipping costs](/core/external-resources/external-shipping-costs#request).
* The **line item** for [external prices](/core/external-resources/external-prices#request) (in this case, the custom includes must be defined at the **market** level to avoid specifying a custom list for each single line item).
* The specific **transaction** for [external payment gateways](/core/external-resources/external-payment-gateways#request).

External includes are not supported for [external order validation](/core/external-resources/external-order-validation). Providing an invalid include for the target resource will result in an error.
{% endhint %}

{% hint style="warning" %}
We strongly recommend limiting the number of included relationships to **a maximum of 10**. Otherwise, the payload will be too large and your external callback could struggle to parse it within the maximum allowed timeout window.
{% endhint %}

{% hint style="danger" %}
If the resource `external_includes` array is populated the provided list **overrides** the default one. The two lists are **not merged**. This means that if you want to add custom includes to the default list, you need to specify a new list containing the default includes plus the new ones.
{% endhint %}

## Response format

The response we require from the external endpoint is a JSON featuring the outcome of the operation, along with some data and error information (if any), based on what type of external resource is involved.

{% tabs %}
{% tab title="Success" %}
In case of success, you can add additional info by populating the response `metadata` object and `messages` array (that information will be stored respectively in the resource's `metadata` attribute and associated `notifications` relationship):

```json
{
  "success": true,
    "data": {
      ...
      "messages": [ ... ],
      "metadata": {
        "foo": "bar"
     }
  }
}
```

{% endtab %}

{% tab title="Error" %}
In case of error, you must respond with an HTTP code >= `400`. You can populate the error object with any other relevant `code` and `message` and add an additional `messages` array that will be stored in the resource's associated `notifications` relationship:

```json
{
  "success": false,
  ...
  "error": {
    "code": "YOUR-ERROR-CODE",
    "message": "Your error message"
  },
  "data": {
    "messages": [ ... ]
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Any external endpoint has **3 seconds** to respond before being timed out.
{% endhint %}

## Notifications

All the external resources, with the exception of external order validation, can automatically add [notifications](/core-api-reference/notifications) to the resource they are called for (for example external promotions can add notifications directly to the order on which they are performing the computation, external prices on the patched line item, etc.), as listed in the table below:

<table><thead><tr><th data-type="content-ref">External resource</th><th data-type="content-ref">Notified resource</th></tr></thead><tbody><tr><td><a href="/pages/yBsAMpp5mRYSq9cuq3J6">/pages/yBsAMpp5mRYSq9cuq3J6</a></td><td></td></tr><tr><td><a href="/pages/-MINswXBrFGQ3Rh9q_vI">/pages/-MINswXBrFGQ3Rh9q_vI</a></td><td><a href="/spaces/RWJeylueWkzLadK710XZ/pages/6uDe19hN1n3RukEDtfKW">/spaces/RWJeylueWkzLadK710XZ/pages/6uDe19hN1n3RukEDtfKW</a></td></tr><tr><td><a href="/pages/4ObKZy8UCZdjCuGZkifX">/pages/4ObKZy8UCZdjCuGZkifX</a></td><td><a href="/spaces/RWJeylueWkzLadK710XZ/pages/B709Shyynvn8yWIk4b27">/spaces/RWJeylueWkzLadK710XZ/pages/B709Shyynvn8yWIk4b27</a></td></tr><tr><td><a href="/pages/-MINsrELiArGzpBvrn5u">/pages/-MINsrELiArGzpBvrn5u</a></td><td><a href="/spaces/RWJeylueWkzLadK710XZ/pages/MVwL5YXa5RKBxVrhQlHo">/spaces/RWJeylueWkzLadK710XZ/pages/MVwL5YXa5RKBxVrhQlHo</a></td></tr><tr><td><a href="/pages/-MI-yjYXX35qMwN80HQb">/pages/-MI-yjYXX35qMwN80HQb</a></td><td><a href="/spaces/RWJeylueWkzLadK710XZ/pages/MVwL5YXa5RKBxVrhQlHo">/spaces/RWJeylueWkzLadK710XZ/pages/MVwL5YXa5RKBxVrhQlHo</a></td></tr><tr><td><a href="/pages/-MWeg7s4PI2Nz6kXSjcg">/pages/-MWeg7s4PI2Nz6kXSjcg</a></td><td><a href="/spaces/RWJeylueWkzLadK710XZ/pages/MVwL5YXa5RKBxVrhQlHo">/spaces/RWJeylueWkzLadK710XZ/pages/MVwL5YXa5RKBxVrhQlHo</a></td></tr></tbody></table>

The notifications data must be specified inside the `messages` node of the `data` key of the [response](#response-format), and passed as an array of objects each one containing at least least the `name` and the `body` attributes (pass the `flash` flag if you want mark the notification as temporary):

<table><thead><tr><th>Key</th><th>Type<select><option value="FFPMylDlGjZ3" label="Boolean" color="blue"></option><option value="p5pyDKHChZPn" label="Integer" color="blue"></option><option value="cLY5AewOsUef" label="Float" color="blue"></option><option value="HIvj0GlLwMl3" label="String" color="blue"></option><option value="uriZ4FxWamVK" label="Array" color="blue"></option><option value="bFLjmXlxDR1F" label="Object" color="blue"></option></select></th><th data-type="checkbox">Required</th><th>Description</th></tr></thead><tbody><tr><td><strong><code>name</code></strong></td><td><span data-option="HIvj0GlLwMl3">String</span></td><td>true</td><td>The internal name of the notification.</td></tr><tr><td><strong><code>body</code></strong></td><td><span data-option="bFLjmXlxDR1F">Object</span></td><td>true</td><td>All the information to be notified.</td></tr><tr><td><strong><code>flash</code></strong></td><td><span data-option="FFPMylDlGjZ3">Boolean</span></td><td>false</td><td>Set it to <code>true</code> to mark the notification as temporary (default is <code>false</code>).</td></tr></tbody></table>

{% tabs %}
{% tab title="Success" %}

<pre class="language-json"><code class="lang-json">{
  "success": true,
  "data": {
    ...
<strong>    "messages": [
</strong>      { 
        "name": "free_item",
        "body": { "sku_code": "AAA" },
<strong>        "flash": true 
</strong>      },
      { 
        "name": "fidelity_score",
        "body": { "score": 10000 }
      }
    ],
    "metadata": { ... }
  }
}
</code></pre>

{% endtab %}

{% tab title="Error" %}

<pre class="language-json"><code class="lang-json">{
  "success": false,
  ...
  "error": {
    "code": "YOUR-ERROR-CODE",
    "message": "Your error message"
  },
  "data": {
<strong>    "messages": [
</strong>      { 
        "name": "warning",
        "body": { "message": "Your error message" }
      }
    ]
  }
}
</code></pre>

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
You can add notifications on your response payload whether if it's succeeded or not, just remember to specify the `messages` array within the `data` key.
{% endhint %}

## Request headers

Any request sent to an external endpoint is enriched with the following headers:

<table><thead><tr><th width="337">Header</th><th>Description</th></tr></thead><tbody><tr><td><strong><code>User-Agent</code></strong></td><td>The type of external request, in the format <code>CommerceLayer {{ClassName}}</code> (e.g. <code>CommerceLayer ExternalGateway</code>).</td></tr><tr><td><strong><code>X-CommerceLayer-Signature</code></strong></td><td>The encrypted signature you need to <a href="/pages/-MIOPl2nMJoIW7dGQnpO">verify the callback authenticity</a>.</td></tr><tr><td><strong><code>X-CommerceLayer-TraceId</code></strong></td><td>The ID of the API request that triggered the call to external service (i.e. the <code>trace_id</code> exposed in the <code>meta</code> object of the response to that API request — useful for debugging purposes, and more).</td></tr><tr><td><strong><code>X-CommerceLayer-Topic</code></strong></td><td>The topic of the event that triggered the call to the <a href="/pages/-LgRXkDyTOVet8bHXwDB">webhook</a> callback URL (e.g. <code>orders.place</code> — present only in that specific case). </td></tr></tbody></table>

Additionally (e.g. if you need to trace the calls to your external endpoints on your APM) you can pass the following optional [Trace Context](https://www.w3.org/TR/trace-context/) headers:

<table><thead><tr><th width="237">Header</th><th>Description</th></tr></thead><tbody><tr><td><strong><code>traceparent</code></strong></td><td>Uniquely identifies the request in a tracing system.</td></tr><tr><td><strong><code>tracestate</code></strong></td><td>Extends <code>traceparent</code> with platform-specific span or trace IDs, providing additional vendor-specific trace identification information across different distributed tracing systems.</td></tr></tbody></table>


# External order validation

How to validate orders via external services

Sometimes, you may need to perform custom validation on orders, as an additional step before the order placement. For example, this could be useful in case you want to support different or more complex validation rules specific to your business logic.

If you want to use the external order validation feature in a [market](/core-api-reference/markets), fill in the market's `external_order_validation_url` field with your external service endpoint and make sure your service is compliant with the specifications described below.

### Triggering external validation

When you want to validate an order based on your external logic, [update](/core-api-reference/orders/update) it and set the `_validate` attribute to `true`:

<pre class="language-shell"><code class="lang-shell">curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/orders/xYZkjABcde' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "orders",
      "id": "xYZkjABcde",
      "attributes": {
<strong>        "_validate": true
</strong>      }
    }
  }'
</code></pre>

Upon this call, Commerce Layer triggers a `POST` request to the specified `external_validation_url` endpoint, sending the order payload (including the related line items) in the request body.

{% hint style="info" %}
To check if an external order validation has been triggered you can inspect the order's `validations_count` attribute and make sure it gets incremented.
{% endhint %}

{% hint style="warning" %}
If the external validation fails the API responds to the `PATCH` above with a `422` error, showing the message(s) that your logic has returned. Please note that **the order is not marked as invalid and can still be placed** (in case it passes the standard, automatic validation at the time of placement). External validation errors are stored (until order approval) in [resource errors](/core-api-reference/resource_errors) which cannot be fetched by a sales channel (e.g. directly from the customer), so it's up to the client side to warn customers about them.
{% endhint %}

### Request

The request payload is a [JSON:API](https://jsonapi.org)-compliant object you can query to perform your own computation. Aside from the **target resource** — `order` in this specific case — some **relationships** are also included to avoid useless API roundtrips:

* `billing_address`
* `shipping_address`
* `line_items.item`
* `line_items`
* `market`
* `customer`
* `shipments`
* `shipments.shipping_method`

<pre class="language-json"><code class="lang-json">{
  "data": {
    "id": "wBXVhKzrnq",
<strong>    "type": "orders",
</strong>    "links": { ... },
    "attributes": { ... },
    "relationships": { ... },
    "meta": { ... }
  },
  "included": [
    {
      "id": "DvlGRmhdgX",
<strong>      "type": "markets",
</strong>      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "kdPgtRXOKL",
<strong>      "type": "line_items",
</strong>      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "XGZwpOSrWL",
<strong>      "type": "skus",
</strong>      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    }
    {
      "id": "BgnguJvXmb",
<strong>      "type": "addresses",
</strong>      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "AlrkugwyVW",
<strong>      "type": "addresses",
</strong>      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "FdefrQxCba",
<strong>      "type": "shipments",
</strong>      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "SfdyHtjfBF",
<strong>      "type": "shipping_methods",
</strong>      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    { ... }
  ]
}
</code></pre>

{% hint style="warning" %}
In case the call to your external endpoint goes timeout, responds with an internal server error, or is blocked by the open [circuit breaker](/core/external-resources#circuit-breaker), the API keeps responding with a `200 OK` status code. No validation errors are attached to the order, but the `validations_count` value and the circuit breaker internal counter (if closed) are incremented.
{% endhint %}

{% hint style="danger" %}
The [override of the default list](/core/external-resources#custom-include-list) of included resources is not supported for external order validation.
{% endhint %}

### Response

Your service response (or error) must match the format described in the example below.

{% hint style="info" %}
Remember to pass the attribute-specific errors within the `data` object, associating them with the related order's attribute. If some error is not associated with any particular attribute use the `base` key (automatically filled with the error messages associated with any invalid attribute, if present).
{% endhint %}

#### Example

{% tabs %}
{% tab title="Response" %}
The successful response must be a JSON object, returning an empty body, meaning that the external logic running the validation has found no errors:

```json
{
  "success": true,
  "data": {}
}
```

{% endtab %}

{% tab title="Error" %}
On error, you must respond with an HTTP code >= `400`. The response body must be a JSON object containing the names of the order's attributes that generated the error(s) and one (a string) or more (an array) associated error message(s) as the value of the `data` key, plus any other relevant error code and message as the value of the `error` key:

```json
{
  "success": false,
  "data": {
    "line_items": ["must be at least 3", "cannot weight more than 2000gr"],
    "shipping_address": "is not recognized by our geo-location service",
    "base": "standard error"
  },
  "error": {
    "code": "YOUR-ERROR-CODE",
    "message": "Your error message"
  }
}
```

{% endtab %}
{% endtabs %}

### Security

When you activate external validation, a **shared secret** is generated at the market level. We recommend verifying the callback authenticity by signing the payload with that shared secret and comparing the result with the callback signature header.

{% content-ref url="/pages/-MIOPl2nMJoIW7dGQnpO" %}
[Callbacks security](/core/callbacks-security)
{% endcontent-ref %}


# External prices

How to manage prices via external services

Sometimes, you can decide not to manage prices within Commerce Layer but use an external service instead. You may want to do that in order to support more dynamic pricing or just leverage an existing service that you want to keep as your system of records.

If you want to use the external prices feature in a [market](/core-api-reference/markets), fill in the market's `external_prices_url` field with your external service endpoint and make sure your service is compliant with the specifications described below.

### Fetching external prices

When you [add a line item](/core-api-reference/line_items/create) to an order, set the `_external_price` attribute to `true` if you want the line item price to be provided by your external service, instead of Commerce Layer:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/line_items' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "line_items",
      "attributes": {
        "quantity": 2,
        "sku_code": "TSHIRTMM000000FFFFFFXLXX",
        "_external_price": true
      },
      "relationships": {
        "order": {
         "data": {
            "type": "orders",
            "id": "QWERtyUpBa"
          }
        }
      }
    }
  }'
```

Upon line item creation, Commerce Layer triggers a `POST` request to the specified `external_prices_url` endpoint, sending the line item payload (including the order) in the request body.

{% hint style="info" %}
Once the external price trigger is set for a line item, any following computation on that line item's price will be performed invoking your external endpoint. If, for some reason, you want to stop using the external service for the price computation and use the price from the market [price list](/core-api-reference/price_lists) (or [price tier](/core-api-reference/price_tiers)), you just need to `PATCH` the line item setting the `_external_price` trigger attribute to `false`.
{% endhint %}

### Request

The request payload is a [JSON:API](https://jsonapi.org)-compliant object you can query to perform your own computation. Aside from the **target resource** — `line_items` in this specific case — some **relationships** are also included to avoid useless API roundtrips:

* `order`
* `order.customer`
* `order.customer.tags`
* `order.line_items`
* `order.market`
* `item`

```json
{
  "data": {
    "id": "xYZkjABcde",
    "type": "line_items",
    "links": { ... },
    "attributes": {
      "quantity": 2,
      "sku_code": "TSHIRTMM000000FFFFFFXLXX",
      "_external_price": true
    },
    "relationships": { ... },
    "meta": { ... }
  },
  "included": [
    {
      "id": "wBXVhKzrnq",
      "type": "orders",
      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "bGvCXzYgNB",
      "type": "customers",
      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "YawgnfmKad",
      "type": "tags",
      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "hJnnKTGfRd",
      "type": "line_items",
      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "DvlGRmhdgX",
      "type": "markets",
      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "XGZwpOSrWL",
      "type": "skus",
      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    }
  ]
}
```

{% hint style="info" %}
If needed, you can [overwrite the default list](/core/external-resources#custom-include-list) of included resources by passing your custom list of line item's relationships within the `external_includes` attribute of the market at creation or update time (nested relationships are allowed using dot notation).
{% endhint %}

{% hint style="warning" %}
In case the call to your external endpoint goes timeout, responds with an internal server error, or is blocked by the open [circuit breaker](/core/external-resources#circuit-breaker), the API responds with a `422` status code by using the [response](#response) error message. The circuit breaker internal counter (if closed) is incremented.
{% endhint %}

### Response

Your service response (or error) must match the format described in the example below.

#### Example

{% tabs %}
{% tab title="Response" %}
The successful response must be a JSON object, returning at least the unit price computed by the external logic and the SKU code of the related product. If needed, you can optionally enrich the response with some additional information, notification messages, and metadata:

<pre class="language-json"><code class="lang-json">{
  "success": true,
  "data": {
<strong>    "sku_code": "TSHIRTMM000000FFFFFFXLXX",
</strong><strong>    "unit_amount_cents": 4900,
</strong>    "messages": [ ... ],
    "metadata": {
      "foo": "bar"
    }
  }
}
</code></pre>

{% endtab %}

{% tab title="Error" %}
On error, you must respond with an HTTP code >= `400`. The response body must be a JSON object containing any other relevant error code and message:

```json
{
  "success": false,
  "error": {
    "code": "YOUR-ERROR-CODE",
    "message": "Your error message"
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
If needed, you can specify in the response also the `compare_at_amount_cents` of the price, which should be greater than the `unit_amount_cents`. If not (i.e. if it's not specified or lower than the unit amount) it will be automatically set as equal to the `unit_amount_cents`.
{% endhint %}

{% hint style="info" %}
If you specify the `messages` key a [notification](/core/external-resources#notifications) with the related information is automatically attached to the patched line item.
{% endhint %}

### SKUs availability

When you fetch a list of SKUs with a sales channel, you only get those SKUs that have a price defined in the market's price list and at least a stock item in one of the market stock locations.

{% hint style="info" %}
In case you manage prices externally, the price filter is not considered.
{% endhint %}

### Security

When you activate external prices, a **shared secret** is generated at the market level. We recommend verifying the callback authenticity by signing the payload with that shared secret and comparing the result with the callback signature header.

{% content-ref url="/pages/-MIOPl2nMJoIW7dGQnpO" %}
[Callbacks security](/core/callbacks-security)
{% endcontent-ref %}


# External shipping costs

How to manage shipping methods cost via external services

Sometimes, you can decide not to manage the price of a shipping method within Commerce Layer but use an external service instead. You may want to do that in order to support more dynamic or custom shipment pricing or just leverage an existing service that you want to keep as your system of records.

If you want to use the external shipping cost feature for one (or more) of your shipping methods, fill in the [shipping method](/core-api-reference/shipping_methods)'s `external_prices_url` field with your external service endpoint and make sure your service is compliant with the specifications described below.

### Fetching external shipping method costs

Set the `scheme` attribute to `external` if you want the shipping method's price to be provided by your external service, overriding the shipping method's `price_amount_cents` you set at creation time. Also, remember to specify the `external_prices_url` if you haven't already set it via the dashboard UI when creating the shipping method:

<pre class="language-bash"><code class="lang-bash">curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/shipping_methods/QWERtyUpBa' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "shipping_methods",
    "id": "QWERtyUpBa",
    "attributes": {
<strong>      "scheme": "external",
</strong><strong>      "external_prices_url": "https://external_prices.yourbrand.com"
</strong>    },
  }
}'
</code></pre>

When the external shipping method is associated with a shipment, Commerce Layer triggers a `POST` request to the specified `external_prices_url` endpoint, sending the shipment payload (including the associated shipping method and order) in the request body.

{% hint style="info" %}
For performance reasons, when [fetching the available shipping methods](https://docs.commercelayer.io/core/external-resources/spaces/-Lk-ezuDClaMavTqnRi0/pages/-LyDmO63mY7E0Z-rsf5x#1.-get-the-available-shipping-methods) for an order the price is not updated with the value calculated externally which is fetched only when the shipping method is [selected](https://docs.commercelayer.io/core/external-resources/spaces/-Lk-ezuDClaMavTqnRi0/pages/-LyDmO63mY7E0Z-rsf5x#3.-select-a-shipping-method).
{% endhint %}

### Request

The request payload is a [JSON:API](https://jsonapi.org)-compliant object you can query to perform your own computation. Aside from the **target resource** — `shipments` in this specific case — the associated shipping method and order are also included as a relationship:

<pre class="language-json"><code class="lang-json">{
  "data":{
    "id":"pMeKKdCwez",
<strong>    "type":"shipments",
</strong>    "links":{ ... },
    "attributes":{
      "number": "#1234/S/001",
      "status": "draft",
      "currency_code": "EUR",
      "cost_amount_cents": 1000,
      "cost_amount_float": 10.0,
      "formatted_cost_amount": "€10,00",
      "skus_count": 2,
      "selected_rate_id": "rate_f89e4663c3ed47ee94d37763f6d21d54",
      "rates":[ ... ],
      "purchase_error_code":null,
      "purchase_error_message":null,
      "get_rates_errors":[ ... ],
      "get_rates_started_at": "2018-01-01T12:00:00.000Z",
      "get_rates_completed_at": "2018-01-01T12:00:00.000Z",
      "purchase_started_at": "2018-01-01T12:00:00.000Z",
      "purchase_completed_at": "2018-01-01T12:00:00.000Z",
      "purchase_failed_at": "2018-01-01T12:00:00.000Z",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata":{ ... }
    },
    "relationships":{ ... },
    "meta":{ ... }
  },
  "included": [
    {
      "id": "wBXVhKzrnq",
<strong>      "type": "shipping_methods",
</strong>      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "fXCNrSklry",
<strong>      "type": "orders",
</strong>      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    }
  ]
}
</code></pre>

{% hint style="info" %}
If needed, you can [overwrite the default list](/core/external-resources#custom-include-list) of included resources by passing your custom list of shipment's relationships within the `external_includes` attribute of the shipping method at creation or update time (nested relationships are allowed using dot notation).
{% endhint %}

{% hint style="warning" %}
In case the call to your external endpoint goes timeout, responds with an internal server error, or is blocked by the open [circuit breaker](/core/external-resources#circuit-breaker), the API keeps responding with a `200 OK` status code. The default shipping price is used (if any) and the circuit breaker internal counter (if closed) is incremented.
{% endhint %}

### Response

Your service response (or error) must match the format described in the example below.

#### Example

{% tabs %}
{% tab title="Response" %}
The successful response must be a JSON object, returning at leat the shipping method's price computed by the external logic. If needed, you can optionally enrich the response with some additional information, notification messages, and metadata:

<pre class="language-json"><code class="lang-json">{
  "success": true,
  "data": {
<strong>    "price_amount_cents": 1700,
</strong>    "messages": [ ... ],
    "metadata": {
      "foo": "bar"
    }
  }
}
</code></pre>

{% endtab %}

{% tab title="Error" %}
On error, you must respond with an HTTP code >= `400`. The response body must be a JSON object containing any other relevant error code and message:

```json
{
  "success": false,
  "error": {
    "code": "YOUR-ERROR-CODE",
    "message": "Your error message"
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
If you specify the `messages` key a [notification](/core/external-resources#notifications) with the related information is automatically attached to the patched shipping method.
{% endhint %}

### Security

When you activate external shipping method costs, a **shared secret** is generated at the shipping method level. We recommend verifying the callback authenticity by signing the payload with that shared secret and comparing the result with the callback signature header.

{% content-ref url="/pages/-MIOPl2nMJoIW7dGQnpO" %}
[Callbacks security](/core/callbacks-security)
{% endcontent-ref %}


# External payment gateways

How to manage payments and transactions via external services

Commerce Layer is [integrated](https://docs.commercelayer.io/developers/v/how-tos/payments) with some of the most popular payment gateways — **Adyen**, **Axerve**, **Braintree**, **Checkout.com**, **Klarna**, **Paypal**, and **Stripe**. They are all compliant with the PSD2 European regulation so that you can implement a payment flow that supports SCA and 3DS2.

Adding new payment gateways to our core is already provided for in our roadmap. Anyway, you already have the complete flexibility to connect to whichever payment service provider you may need. To do that, just create an external payment gateway and define your custom endpoint(s) responding to the following actions:

1. [Authorization](#authorization) — to authorize a payment source
2. [Capture](#capture) — to capture an authorization
3. [Void](#void) — to void an authorization
4. [Refund](#refund) — to refund a capture, either totally or partially
5. [Customer token](#customer-token) — to create a customer payment token

Your external endpoint will be responsible for the actual integration with the payment gateway. The payment source associated with the order must be an [external payment](https://docs.commercelayer.io/developers/v/api-reference/external_payments).

{% hint style="info" %}
External gateways process payments **synchronously** by default. If you need your gateway to behave differently, check the [asynchronous payments section](#asynchronous-payments).
{% endhint %}

### Request

The request payload is a [JSON:API](https://jsonapi.org/) compliant object you can query to perform your own computation. Aside from the **target resource** — which depends on the kind of gateway's transaction — some **relationships** are also included to avoid useless API roundtrips:

* `order`
* `order.market`
* `order.line_items`
* `order.line_items.item`
* `order.shipping_address`
* `order.billing_address`
* `order.customer`
* `order.order_subscriptions`

```json
{
  "data": {
    ...
  },
  "included": [
    {
      "id": "wBXVhKzrnq",
      "type": "orders",
      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "DvlGRmhdgX",
      "type": "markets",
      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "kdPgtRXOKL",
      "type": "line_items",
      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "XGZwpOSrWL",
      "type": "skus",
      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "BgnguJvXmb",
      "type": "addresses",
      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "AdcreKwJnd",
      "type": "order_subscriptions",
      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    { ... }
  ]
}
```

{% hint style="info" %}
If needed, you can [overwrite the default list](/core/external-resources#custom-include-list) of included resources by passing your custom list the specific transaction's relationships within the `external_includes` attribute of the external payment gateway at creation or update time (nested relationships are allowed using dot notation).
{% endhint %}

{% hint style="warning" %}
In case the call to your external endpoint goes timeout, responds with an internal server error or is blocked by the open [circuit breaker](/core/external-resources#circuit-breaker), the API keeps responding with a `200 OK` status code. A failed transaction (of the specific type) is created by using the related response error message and the circuit breaker internal counter (if closed) is incremented.
{% endhint %}

### Authorization

When you place an order, Commerce Layer triggers a `POST` request to the endpoint that you specified in the `authorize_url` field and creates an authorization.

#### Example

{% tabs %}
{% tab title="Payload" %}
The request payload contains the external payment resource and includes the [above-mentioned](#request) relationships:

```json
{
  "data": {
    "id": "ZNKjeUYepv",
    "type": "external_payments",
    "links": { ... },
    "attributes": { ... },
    "relationships": { ... },
    "meta": { ... }
  },
  "included": [
    { ... }
  ]
}
```

{% endtab %}

{% tab title="Response" %}
The successful response must be a JSON object, returning at least a transaction token (e.g. the one provided by the payment gateway) and the total amount that has been authorized. If needed, you can optionally enrich the response with some additional information, notification messages, and metadata:

<pre class="language-json"><code class="lang-json">{
  "success": true,
  "data": {
<strong>    "transaction_token": "your-external-transaction-token",
</strong><strong>    "amount_cents": 12900,
</strong>    "messages": [ ... ],
    "metadata": {
      "foo": "bar"
    }
  }
}
</code></pre>

{% hint style="info" %}
If you specify the `messages` key a [notification](/core/external-resources#notifications) with the related information is automatically attached to the associated order.
{% endhint %}
{% endtab %}

{% tab title="Error" %}
On error, you must respond with an HTTP code >= `400`. The response body must be a JSON object containing a transaction token (e.g. the one provided by the payment gateway) and the authorization amount, along with any other relevant error code and message:

```json
{
  "success": false,
  "data": {
    "transaction_token": "your-external-transaction-token",
    "amount_cents": 12900
  },
  "error": {
    "code": "YOUR-ERROR-CODE",
    "message": "Your error message"
  }
}
```

{% endtab %}
{% endtabs %}

### Capture

When you try to capture an authorization, Commerce Layer triggers a `POST` request to the endpoint that you specified in the `capture_url` field and creates a capture.

#### Example

{% tabs %}
{% tab title="Payload" %}
The request payload contains the authorization resource and includes the [above-mentioned](#request) relationships:

```json
{
  "data": {
    "id": "yGzeUJxRJj",
    "type": "authorizations",
    "links": { ... },
    "attributes": { ... },
    "relationships": { ... },
    "meta": { ... }
  },
  "included": [
    { ... }
  ]
}
```

{% endtab %}

{% tab title="Response" %}
The successful response must be a JSON object, returning at least a transaction token (e.g. the one provided by the payment gateway) and the total amount that has been captured. If needed, you can optionally enrich the response with some additional information, notification messages, and metadata:

<pre class="language-json"><code class="lang-json">{
  "success": true,
  "data": {
<strong>    "transaction_token": "your-external-transaction-token",
</strong><strong>    "amount_cents": 12900,
</strong>    "messages" : [ ... ],
    "metadata": {
      "foo": "bar"
    }
  }
}
</code></pre>

{% hint style="info" %}
If you specify the `messages` key a [notification](/core/external-resources#notifications) with the related information is automatically attached to the associated order.
{% endhint %}
{% endtab %}

{% tab title="Error" %}
On error, you must respond with an HTTP code >= `400`. The response must be a JSON object containing a transaction token (e.g. the one provided by the payment gateway) and the capture amount, along with any other relevant error code and message:

```json
{
  "success": false,
  "data": {
    "transaction_token": "your-external-transaction-token",
    "amount_cents": 12900
  },
  "error": {
    "code": "YOUR-ERROR-CODE",
    "message": "Your error message"
  }
}
```

{% endtab %}
{% endtabs %}

### Void

When you try to void an authorization, Commerce Layer triggers a `POST` request to the endpoint that you specified in the `void_url` field and creates a void.

#### Example

{% tabs %}
{% tab title="Payload" %}
The request payload contains the authorization resource and includes the [above-mentioned](#request) relationships:

```json
{
  "data": {
    "id": "yGzeUJxRJj",
    "type": "authorizations",
    "links": { ... },
    "attributes": { ... },
    "relationships": { ... },
    "meta": { ... }
  },
  "included": [
    { ... }
  ]
}
```

{% endtab %}

{% tab title="Response" %}
The successful response must be a JSON object, returning at least a transaction token (e.g. the one provided by the payment gateway) and the total amount that has been voided. If needed, you can optionally enrich the response with some additional information, notification messages, and metadata:

<pre class="language-json"><code class="lang-json">{
  "success": true,
  "data": {
<strong>    "transaction_token": "your-external-transaction-token",
</strong><strong>    "amount_cents": 12900,
</strong>    "messages": [ ... ],
    "metadata": {
      "foo": "bar"
    }
  }
}
</code></pre>

{% hint style="info" %}
If you specify the `messages` key a [notification](/core/external-resources#notifications) with the related information is automatically attached to the associated order.
{% endhint %}
{% endtab %}

{% tab title="Error" %}
On error, you must respond with an HTTP code >= `400`. The response must be a JSON object containing a transaction token (e.g. the one provided by the payment gateway) and the void amount, along with any other relevant error code and message:

```json
{
  "success": false,
  "data": {
    "transaction_token": "your-external-transaction-token",
    "amount_cents": 12900
  },
  "error": {
    "code": "YOUR-ERROR-CODE",
    "message": "Your error message"
  }
}
```

{% endtab %}
{% endtabs %}

### Refund

When you try to void a capture, Commerce Layer triggers a `POST` request to the endpoint that you specified in the `refund_url` field and creates a refund.

#### Example

{% tabs %}
{% tab title="Payload" %}
The request payload contains the capture resource and includes the [above-mentioned](#request) relationships:

```json
{
  "data": {
    "id": "yJQDUVndWj",
    "type": "captures",
    "links": { ... },
    "attributes": { ... },
    "relationships": { ... },
    "meta": { ... }
  },
  "included": [
    { ... }
  ]
}
```

{% endtab %}

{% tab title="Response" %}
The successful response must be a JSON object, returning at least a transaction token (e.g. the one provided by the payment gateway) and the amount that has been refunded. If needed, you can optionally enrich the response with some additional information, notification messages, and metadata:

<pre class="language-json"><code class="lang-json">{
  "success": true,
  "data": {
<strong>    "transaction_token": "your-external-transaction-token",
</strong><strong>    "amount_cents": 9900,
</strong>    "messages": [ ... ],
    "metadata": {
      "foo": "bar"
    }
  }
}
</code></pre>

{% hint style="info" %}
If you specify the `messages` key a [notification](/core/external-resources#notifications) with the related information is automatically attached to the associated order.
{% endhint %}
{% endtab %}

{% tab title="Error" %}
On error, you must respond with an HTTP code >= `400`. The response must be a JSON object containing a transaction token (e.g. the one provided by the payment gateway) and the refund amount, along with any other relevant error code and message:

```json
{
  "success": false,
  "data": {
    "transaction_token": "your-external-transaction-token",
    "amount_cents": 9900
  },
  "error": {
    "code": "YOUR-ERROR-CODE",
    "message": "Your error message"
  }
}
```

{% endtab %}
{% endtabs %}

### Customer token

When you try to store a payment token for a customer, Commerce Layer triggers a `POST` request to the endpoint that you specified in the `token_url` field and creates a customer payment source for the specified payment.

#### Example

{% tabs %}
{% tab title="Payload" %}
The request payload contains the payment source resource and includes the [above-mentioned](#request) relationships:

```json
{
  "data": {
    "id": "GBNMKjUkry",
    "type": "external_payments",
    "links": { ... },
    "attributes": { ... },
    "relationships": { ... },
    "meta": { ... }
  },
  "included": [
    { ... }
  ]
}
```

{% endtab %}

{% tab title="Response" %}
The successful response must be a JSON object, returning an optional `customer_token` (if missing the `customer.email` is used) and the `payment_source_token` that represents the saved payment for the customer:

<pre class="language-json"><code class="lang-json">{
  "success": true,
  "data": {
<strong>    "customer_token": "your-external-customer-token",
</strong><strong>    "payment_source_token": "your-external-payment-source-token"
</strong>    }
  }
}
</code></pre>

{% endtab %}

{% tab title="Error" %}
On error, you must respond with an HTTP code >= `400`. The response must be a JSON object containing other relevant error code and message:

```json
{
  "success": false,
  "error": {
    "code": "YOUR-ERROR-CODE",
    "message": "Your error message"
  }
}
```

{% endtab %}
{% endtabs %}

### Asynchronous payments

It might be the case you don't want your gateway to process payments immediately. That's why Commerce Layer provides the option to [mark](#action-id) your external gateway response as **asynchronous** and [exposes](#webhook-endpoint) a `webhook_endpoint_url` you can call once the payment status changes.

{% hint style="info" %}
The `token_url` doesn't support asynchronous execution.
{% endhint %}

#### Action ID

A payment is marked as asynchronous when the following conditions on the response to any of the external payment gateway transactions are met:

* HTTP code is `202`
* It contains the `action_id` key, which *uniquely* identifies the related transaction

{% hint style="info" %}
`action_id` uniqueness is mandatory for the [webhook](#webhook-endpoint) to detect the transaction later.
{% endhint %}

In this case, the external payment gateway creates the transaction setting the `succeeded` attribute to `false`, but considering it as pending. This way, the order can be placed without errors, but the order payment status doesn't change yet (even if the order is not editable anymore).

#### Example

{% tabs %}
{% tab title="Payload" %}
The payload requested by the related transaction, as explained in the [authorization](#authorization), [capture](#capture), [void](#void), and [refund](#refund) sections.
{% endtab %}

{% tab title="Response" %}
The successful response must be a JSON object, returning a transaction token (e.g. the one provided by the payment gateway), the amount involved, and the unique identifier of the transaction. If needed, you can add some metadata that will be copied into the related transaction resource that is being created:

```json
{
  "success": true,
  "data": {
    "transaction_token": "your-external-transaction-token",
    "amount_cents": 12900,
    "action_id": "your-action-id",
    "metadata": {
      "foo": "bar"
    }
  }
}
```

{% endtab %}

{% tab title="Error" %}
On error, you must respond with an HTTP code >= `400`. The response must be a JSON object containing a transaction token (e.g. the one provided by the payment gateway) and the amount involved in the transaction, along with any other relevant error code and messagee:

```json
{
  "success": false,
  "data": {
    "transaction_token": "your-external-transaction-token",
    "amount_cents": 12900
  },
  "error": {
    "code": "YOUR-ERROR-CODE",
    "message": "Your error message"
  }
}
```

{% endtab %}
{% endtabs %}

#### Webhook endpoint

To notify the payment has changed its status, the external gateway exposes a `webhook_endpoint_url` you can call accordingly once the related payment transaction gets an update, as long as you follow these requirements:

* It accepts only POST requests.
* You must include an **X-CommerceLayer-Signature** header, which contains the [HMAC](https://en.wikipedia.org/wiki/HMAC) of the request payload signed with a **SHA256** algorithm and the same [shared secret](#security) already exposed by the external payment gateway.
* The request body must have the same structure as the response — a JSON object with the transaction's attributes you need to update — and include the `action_id` previously used.

The external payment gateway will use this data to fetch the pending transaction and update the attributes with the new values. On successful update, the transaction `succeeded` attribute is set to `true` and the order is updated to the right status — `authorized`, `paid`, `voided`, or `refunded`. In case of error, the order status remains as it is.

{% hint style="info" %}
The `webhook_endpoint_url` is generated upon the external gateway creation and you can find it in the gateway's details page on the admin dashboard.
{% endhint %}

#### Updatable attributes

Only a subset of attributes is allowed for an update, assuming the main ones have already been set by [the first async response](#action-id) (e.g. `amount_cents` and `transaction_token` cannot be updated). The updatable transaction fields are:

* `message`
* `error_code`
* `error_detail`
* `avs_code`
* `avs_message`
* `cvv_code`
* `cvv_message`
* `fraud_review`

### Security

When you create a new external payment gateway, a **shared secret** is generated. We recommend verifying the callback authenticity by signing the payload with that shared secret and comparing the result with the callback signature header.

{% content-ref url="/pages/-MIOPl2nMJoIW7dGQnpO" %}
[Callbacks security](/core/callbacks-security)
{% endcontent-ref %}


# External promotions

How to manage custom promotions via external services

Besides the promotion types that are supported out-of-the-box ([buy X pay Y](/core-api-reference/buy_x_pay_y_promotions), [fixed amount](https://docs.commercelayer.io/developers/v/api-reference/fixed_amount_promotions),  [fixed price](https://docs.commercelayer.io/developers/v/api-reference/fixed_price_promotions), [free gift](https://docs.commercelayer.io/developers/v/api-reference/free_gift_promotions), [free shipping](https://docs.commercelayer.io/developers/v/api-reference/free_shipping_promotions), and [percentage discount](https://docs.commercelayer.io/developers/v/api-reference/percentage_discount_promotions)) Commerce Layer lets you integrate any kind of promotional engine as an [external promotion](https://docs.commercelayer.io/developers/v/api-reference/external_promotions).

When an external promotion activates — i.e. its activation rules are met — Commerce Layer triggers a `POST` request to the `promotion_url` endpoint, sending the order payload (including its line items) in the request body.

### Request

The request payload is a [JSON:API](https://jsonapi.org/) compliant object you can query to perform your own computation. Aside from the **target resource** — `orders` in the specific case — some **relationships** are also included to avoid useless API roundtrips:

* `market`
* `customer`
* `customer.tags`
* `line_items`
* `line_items.item`
* `shipping_address`
* `billing_address`

<pre class="language-json"><code class="lang-json">{
  "data": {
    "id": "wBXVhKzrnq",
<strong>    "type": "orders",
</strong>    "links": { ... },
    "attributes": { ... },
    "relationships": { ... },
    "meta": { ... }
  },
  "included": [
    {
      "id": "DvlGRmhdgX",
<strong>      "type": "markets",
</strong>      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "bGvCXzYgNB",
<strong>      "type": "customers",
</strong>      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "YawgnfmKad",
<strong>      "type": "tags",
</strong>      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "kdPgtRXOKL",
<strong>      "type": "line_items",
</strong>      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "XGZwpOSrWL",
<strong>      "type": "skus",
</strong>      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    }
    {
      "id": "BgnguJvXmb",
<strong>      "type": "addresses",
</strong>      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "AlrkugwyVW",
<strong>      "type": "addresses",
</strong>      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    { ... }
  ]
}
</code></pre>

{% hint style="info" %}
If needed, you can [overwrite the default list](/core/external-resources#custom-include-list) of included resources by passing your custom list of order's relationships within the `external_includes` attribute of the external promotion at creation or update time (nested relationships are allowed using dot notation).
{% endhint %}

{% hint style="warning" %}
In case the call to your external endpoint goes timeout, responds with an internal server error, or is blocked by the open [circuit breaker](/core/external-resources#circuit-breaker), the API keeps responding with a `200 OK` status code. No promotion is added to the order and the circuit breaker internal counter (if closed) is incremented.
{% endhint %}

### Response

Your service response (or error) must match the format described in the examples below.

#### Applying the discount to all taxable items of the order

{% tabs %}
{% tab title="Response" %}
The successful response must be a JSON object, returning at least the discount computed by the external logic. If needed, you can optionally enrich the response with some additional information, notification messages, and metadata:

<pre class="language-json"><code class="lang-json">{
  "success": true,
  "data": {
    "name": "My External Promotion",
<strong>    "discount_cents": 1500,
</strong>    "messages": [ ... ],
    "metadata": {
      "foo": "bar"
    }
  }
}
</code></pre>

{% endtab %}

{% tab title="Error" %}
On error, you must respond with an HTTP code >= `400`. The response body must be a JSON object containing any other relevant error code and message:

<pre class="language-json"><code class="lang-json">{
  "success": false,
  "error": {
<strong>    "code": "YOUR-ERROR-CODE",
</strong><strong>    "message": "Your error message"
</strong>  }
}
</code></pre>

{% endtab %}
{% endtabs %}

#### Applying the discount to specific taxable items

{% tabs %}
{% tab title="Response" %}
The successful response must be a JSON object, returning at least the discount computed by the external logic to be applied to the specified line items. If needed, you can optionally enrich the response with some additional information, notification messages, and metadata:

<pre class="language-json"><code class="lang-json">{
  "success": true,
  "data": {
    "name": "My External Promotion",
<strong>    "discount_cents": 1500,
</strong>    "line_items": [
      {
<strong>        "id": "kxnXtEaGxo"
</strong>      },
      {
<strong>        "id": "kXBqtrgARW"
</strong>      }
    ],
    "messages": [ ... ],
    "metadata": {
      "foo": "bar"
    }
  }
}
</code></pre>

{% endtab %}

{% tab title="Error" %}
On error, you must respond with an HTTP code >= `400`. The response body must be a JSON object containing any other relevant error code and message:

<pre class="language-json"><code class="lang-json">{
  "success": false,
  "error": {
<strong>    "code": "YOUR-ERROR-CODE",
</strong><strong>    "message": "Your error message"
</strong>  }
}
</code></pre>

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
Be aware that specifying the line items in the response will overwrite both the associated SKU list (if any) and the [taxable items](/core-api-reference/orders#taxable-items) options (e.g. you can distribute the discount on a purchased gift card also if the `gift_card_taxable` is `false`). In case any of the provided line item IDs is not associated with the order, no promotion is applied.
{% endhint %}

#### Applying a specific discount to specific taxable items

{% tabs %}
{% tab title="Response" %}
The successful response must be a JSON object, returning at least a specific discount computed by the external logic to be applied to the specified line items. If needed, you can optionally enrich the response with some additional information, notification messages, and metadata:

<pre class="language-json"><code class="lang-json">{
  "success": true,
  "data": {
    "name": "My External Promotion",
    "line_items": [
      {
<strong>        "id": "kxnXtEaGxo",
</strong><strong>        "discount_cents": 1000
</strong>      },
      {
<strong>        "id": "kXBqtrgARW",
</strong><strong>        "discount_cents": 500
</strong>      }
    ],
    "messages": [ ... ],
    "metadata": {
      "foo": "bar"
    }
  }
}
</code></pre>

{% endtab %}

{% tab title="Error" %}
On error, you must respond with an HTTP code >= `400`. The response body must be a JSON object containing any other relevant error code and message:

<pre class="language-json"><code class="lang-json">{
  "success": false,
  "error": {
<strong>    "code": "YOUR-ERROR-CODE",
</strong><strong>    "message": "Your error message"
</strong>  }
}
</code></pre>

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
If you are going to specify the `discount_cents` key for the single line items, make sure to do it for all of the elements of the `line_items` array. Keep in mind that the promotion amount is computed and distributed only for the line items whose IDs are listed in the array with a `discount_cents` key specified.  In this case, avoid adding the `discount_cents` key at order the level because it's ignored if there is any line item with a specific `discount_cents` key set.
{% endhint %}

{% hint style="info" %}
If you specify the `messages` key a [notification](/core/external-resources#notifications) with the related information is automatically attached to the associated order.
{% endhint %}

### Security

When you create a new external promotion, a **shared secret** is generated. We recommend verifying the callback authenticity by signing the payload with that shared secret and comparing the result with the callback signature header.

{% content-ref url="/pages/-MIOPl2nMJoIW7dGQnpO" %}
[Callbacks security](/core/callbacks-security)
{% endcontent-ref %}

####


# External tax calculators

How to manage custom tax calculation via external services

Commerce Layer supports automatic tax calculation thanks to the out-of-the-box integration with [Avalara](/core-api-reference/avalara_accounts), [Stripe Tax](/core-api-reference/stripe_tax_accounts), [TaxJar](/core-api-reference/taxjar_accounts), and [Vertex](/core-api-reference/vertex_accounts). [Manual tax calculators](https://docs.commercelayer.io/developers/v/api-reference/manual_tax_calculators) can be also configured. On top of that, you also have the complete flexibility to implement any particular custom tax calculation logic building your own [external tax calculator](https://docs.commercelayer.io/developers/v/api-reference/external_tax_calculators).

Whenever the tax calculation is fired, Commerce Layer triggers a `POST` request to the `tax_calculator_url` endpoint, sending the order payload (including its line items and their items) in the request body. To trigger the tax update, the order must be not archived and have the following attributes:

* a valid `shipping_address` or a valid `billing_address`
* an `external_tax_calculator` associated with the market in scope
* a positive `total_amount_cent`
* at least one SKU among its line item (gift cards are not taxed)

### Taxes data granularity

External taxes can be applied either to the whole order or to specific line items, depending on how granular your response is. If you need to pass tax values at the line item level and set tax breakdown attributes, you need to include in the response an array containing the line items you want to be affected by the tax update and specify each line item ID, as the payload passed in the request to your external calculator.

### Values precedence

When designing your external tax calculator response, bear in mind that some values take precedence over other ones, according to the following logic.

#### 1. Line item tax collectable

If the `tax_collectable` attribute is specified for a line item, its value is used to compute the `tax_amount_cents` for the line item, no matter what's the value of the line item `tax_rate` (if any).

{% hint style="info" %}
The `tax_collectable` attribute is a `float` (e.g. `"tax_collectable": 9.0` sets the line item `tax_amount_cents` to 900).
{% endhint %}

#### 2. Line item tax rate

If the `tax_collectable` is missing for a line item, the line item `tax_amount_cents` is computed using the line item `tax_rate`.

#### 3. Global tax rate

If both the line item `tax_collectable` and `tax_rate` are missing, the line item `tax_amount_cents` is computed using the `tax_rate` specified at the `data` level. If the line items array is missing, that tax rate is applied to the whole order.

### Request

The request payload is a [JSON:API](https://jsonapi.org/) compliant object you can query to perform your own computation. Aside from the **target resource** — `orders` in the specific case — some **relationships** are also included to avoid useless API roundtrips:

* `market`
* `customer`
* `line_items`
* `line_items.item`
* `shipping_address`
* `billing_address`

<pre class="language-json"><code class="lang-json">{
  "data": {
    "id": "wBXVhKzrnq",
<strong>    "type": "orders",
</strong>    "links": { ... },
    "attributes": { ... },
    "relationships": { ... },
    "meta": { ... }
  },
  "included": [
    {
      "id": "DvlGRmhdgX",
<strong>      "type": "markets",
</strong>      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "DHvfpESrCx",
<strong>      "type": "customers",
</strong>      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "kdPgtRXOKL",
<strong>      "type": "line_items",
</strong>      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "XGZwpOSrWL",
<strong>      "type": "skus",
</strong>      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "BgnguJvXmb",
<strong>      "type": "addresses",
</strong>      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    {
      "id": "AlrkugwyVW",
<strong>      "type": "addresses",
</strong>      "links": { ... },
      "attributes": { ... },
      "relationships": { ... },
      "meta": { ... }
    },
    { ... }
  ]
}
</code></pre>

{% hint style="info" %}
If needed, you can [overwrite the default list](/core/external-resources#custom-include-list) of included resources by passing your custom list of order's relationships within the `external_includes` attribute of the external tax calculator at creation or update time (nested relationships are allowed using dot notation).
{% endhint %}

{% hint style="warning" %}
In case the call to your external endpoint goes timeout, responds with an internal server error, or is blocked by the open [circuit breaker](/core/external-resources#circuit-breaker), the API keeps responding with a `200 OK` status code. No tax amount is updated on the order and the circuit breaker internal counter (if closed) is incremented.
{% endhint %}

### Response

Your service response (or error) must match the format described in the examples below.

#### Applying the same tax rate to the whole order

{% tabs %}
{% tab title="Response" %}
The successful response must be a JSON object, returning at least the tax rate to be applied to the whole order. If needed, you can optionally enrich the response with some additional information, notification messages, and metadata:

<pre class="language-json"><code class="lang-json">{
  "success": true,
  "data": {
<strong>    "tax_rate": 0.25,
</strong>    "messages": [ ... ],
    "metadata": {
      "foo": "bar"
    }
  }
}
</code></pre>

{% endtab %}

{% tab title="Error" %}
On error, you must respond with an HTTP code >= `400`. The response body must be a JSON object containing any other relevant error code and message:

```json
{
  "success": false,
  "error": {
    "code": "YOUR-ERROR-CODE",
    "message": "Your error message"
  }
}
```

{% endtab %}
{% endtabs %}

#### Applying different tax rates for some line items

{% tabs %}
{% tab title="Response" %}
The successful response must be a JSON object, returning at least the specific tax rate to be applied to the line items. If needed, you can optionally enrich the response with some additional information, notification messages, and metadata:

<pre class="language-json"><code class="lang-json">{
  "success": true,
  "data": {
<strong>    "tax_rate": 0.25,
</strong>    "line_items": [
      {
<strong>        "id": "kxnXtEaGxo",
</strong><strong>        "tax_rate": 0.3
</strong>      },
      {
<strong>        "id": "kXBqtrgARW",
</strong><strong>        "tax_rate": 0.4
</strong>      }
    ],
    "messages": [ ... ],
    "metadata": {
      "foo": "bar"
    }
  }
}
</code></pre>

{% endtab %}

{% tab title="Error" %}
On error, you must respond with an HTTP code >= `400`. The response body must be a JSON object containing any other relevant error code and message:

```json
{
  "success": false,
  "error": {
    "code": "YOUR-ERROR-CODE",
    "message": "Your error message"
  }
}
```

{% endtab %}
{% endtabs %}

#### More complex external tax calculations affecting the tax breakdown

{% tabs %}
{% tab title="Response" %}
The successful response must be a JSON object, returning at least specific tax collectable and tax rate values to be applied to the line items, and some attributes you want to set in the line items tax breakdown. If needed, you can optionally enrich the response with some additional information, notification messages, and metadata:

<pre class="language-json"><code class="lang-json">{
  "success": true,
  "data": {
<strong>    "freight_taxable": true,
</strong><strong>    "tax_rate": 0.25,
</strong>    "line_items": [
      {
<strong>        "id": "kxnXtEaGxo",
</strong><strong>        "tax_collectable": 2.25,
</strong><strong>        "country_tax_collectable": 9,
</strong><strong>        "country_tax_rate": 0.2,
</strong><strong>        "country_taxable_amount": 9,
</strong><strong>        "special_tax_rate": 0.05,
</strong><strong>        "taxable_amount": 10,
</strong><strong>        "tax_rate": 0.4
</strong>      },
      {
<strong>        "id": "kXBqtrgARW",
</strong><strong>        "taxable_amount": 12,
</strong><strong>        "tax_rate": 0.3
</strong>      }
    ],
    "messages": [ ... ]
    "metadata": {
      "foo": "bar"
    }
  }
}
</code></pre>

{% endtab %}

{% tab title="Error" %}
On error, you must respond with an HTTP code >= `400`. The response body must be a JSON object containing any other relevant error code and message:

```json
{
  "success": false,
  "error": {
    "code": "YOUR-ERROR-CODE",
    "message": "Your error message"
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
If you specify the `messages` key a [notification](/core/external-resources#notifications) with the related information is automatically attached to the associated order.
{% endhint %}

### Security

When you create a new external tax calculator, a **shared secret** is generated. We recommend verifying the callback authenticity by signing the payload with that shared secret and comparing the result with the callback signature header.

{% content-ref url="/pages/-MIOPl2nMJoIW7dGQnpO" %}
[Callbacks security](/core/callbacks-security)
{% endcontent-ref %}


# Rate limits

Information about the restrictions on the number of times a user or client can access Commerce Layer API endpoints within a specified period of time.

To protect our platform against API misuse or overuse and ensure the system is available for all our users we adopt a rate-limiting strategy, differentiated by [environment](/core/api-specification#environments) (*test* or *live*), HTTP method, and types of resources involved.

{% hint style="danger" %}
IP addresses that exceed the following rates will be blocked until the frequency of the specific call drops below the allowed limit. Please note that the count on the number of requests **is never reset**: you must consider the time intervals as sliding time windows (that's why no `X-Ratelimit-Reset` header is [included in the response](#response-headers)).
{% endhint %}

{% hint style="success" %}
If you're using Commerce Layer [JS SDK](https://github.com/commercelayer/commercelayer-sdk) to interact with our Core API you can leverage the [SDK Utils](https://github.com/commercelayer/commercelayer-sdk-utils) library to execute several API calls to a resource endpoint in batch and make sure not to hit the current rate limits ([see example](https://github.com/commercelayer/commercelayer-sdk-utils?tab=readme-ov-file#executebatch)).
{% endhint %}

## Authentication endpoint

All the requests to the `/oauth/token` endpoint to get an access token to [authenticate](/core/authentication) your API calls are never cached and are subject to stricter rate limits, regardless of the environment:

| Environment | Max number of requests | Time window |
| ----------- | ---------------------- | ----------- |
| Live, Test  | **30**                 | **1 min**   |

## Other endpoints

All the [resources](https://docs.commercelayer.io/core-api-reference/) endpoint can be grouped into two main classes depending on whether they could be cached or not (*cacheable* or *uncacheable*). Two kinds of rate limits are applied to the IP with which you perform the calls to the `/api/*` endpoints:

* **Average** — the number of requests is calculated considering the *sum* of the requests sent to *all* the resource endpoints of the specific class in the related time window (e.g. you cannot send 400 live reqs to the `/api/bundles` endpoint, 400 live reqs to the `/api/skus endpoint`, and 400 live reqs to the `/api/prices` endpoint, all within the same 1-min window — because it would result in a total of 1200 reqs / 1 min).
* **Burst** — the number of requests is calculated on *each* single resource endpoint of the specific class (e.g. you can send 25 test reqs to the `/api/addresses` endpoint, 25 test reqs to the `/api/orders` endpoint, and 25 test reqs to the `/api/line_items` endpoint, all within the same 10-sec window)

### Read requests

Read requests (performed via `GET`,  `HEAD`, or `OPTIONS` HTTP methods) are subject to different rate limits based on the type of resource.

#### Cacheable

Please find below the list of *cacheable* resources. Read requests to the related endpoints are subject to the following rate limits:

<table><thead><tr><th>Environment</th><th>Limit type</th><th width="222">Max number of requests</th><th>Time window</th></tr></thead><tbody><tr><td>Live</td><td><em>Average</em></td><td><strong>1000</strong> (to all endpoints)</td><td><strong>1 min</strong></td></tr><tr><td>Test</td><td><em>Avera</em>ge</td><td><strong>500</strong> (to all endpoints)</td><td><strong>1 min</strong></td></tr><tr><td>Live</td><td><em>Burst</em></td><td><strong>250</strong> (per endpoint)</td><td><strong>10 secs</strong></td></tr><tr><td>Test</td><td><em>Burst</em></td><td><strong>125</strong> (per endpoint)</td><td><strong>10 secs</strong></td></tr></tbody></table>

<details>

<summary>Cacheable resources list</summary>

* [Bundles](/core-api-reference/bundles) — `/api/bundles`
* [Imports](/core-api-reference/imports) — `/api/imports`
* [Markets](/core-api-reference/markets) — `/api/markets`
* [Prices](/core-api-reference/prices) — `/api/prices`
* [Price list](/core-api-reference/price_lists) — `/api/price_lists`
* [Promotions](/core-api-reference/promotions) — `/api/promotions`
* All types of promotions — `/api/*_promotions`
  * [Buy X pay Y promotions](/core-api-reference/buy_x_pay_y_promotions) — `/api/buy_x_pay_y_promotions`
  * [External promotions](/core-api-reference/external_promotions) — `/api/external_promotions`
  * [Fixed amount promotions](/core-api-reference/fixed_amount_promotions) — `/api/fixed_amount_promotions`
  * [Fixed price promotions](/core-api-reference/fixed_price_promotions) — `/api/fixed_price_promotions`
  * [Free gift promotions](/core-api-reference/free_gift_promotions) — `/api/free_gift_promotions`
  * [Free shipping promotions](/core-api-reference/free_shipping_promotions) — `/api/free_shipping_promotions`
  * [Percentage discount promotions](/core-api-reference/percentage_discount_promotions) — `/api/percentage_discount_promotions`
* [SKUs](/core-api-reference/skus) — `/api/skus`
* [SKU options](/core-api-reference/sku_options) — `/api/sku_options`
* [Stock items](/core-api-reference/stock_items) — `/api/stock_items`
* [Stock locations](/core-api-reference/stock_locations) — `/api/stock_locations`

</details>

#### Uncacheable

Read requests to all other endpoints (not listed [above](#cachable)) are subject to the following rate limits:

<table><thead><tr><th width="164">Environment</th><th>Limit type</th><th width="225">Max number of requests</th><th>Time window</th></tr></thead><tbody><tr><td>Live</td><td><em>Average</em></td><td><strong>200</strong> (to all endpoints)</td><td><strong>1 min</strong></td></tr><tr><td>Test</td><td><em>Average</em></td><td><strong>100</strong> (to all endpoints)</td><td><strong>1 min</strong></td></tr><tr><td>Live</td><td><em>Burst</em></td><td><strong>50</strong> (per endpoint)</td><td><strong>10 secs</strong></td></tr><tr><td>Test</td><td><em>Burst</em></td><td><strong>25</strong> (per endpoint)</td><td><strong>10 secs</strong></td></tr></tbody></table>

### Write requests

Write requests (performed via `POST`, `PUT`,  `PATCH`, or `DELETE` HTTP methods) to **any** endpoint (regardless of whether the related resource falls into the *cacheable* or *uncacheable* category) are subject to the following rate limits:

<table><thead><tr><th width="164">Environment</th><th>Limit type</th><th width="225">Max number of requests</th><th>Time window</th></tr></thead><tbody><tr><td>Live</td><td><em>Average</em></td><td><strong>200</strong> (to all endpoints)</td><td><strong>1 min</strong></td></tr><tr><td>Test</td><td><em>Average</em></td><td><strong>100</strong> (to all endpoints)</td><td><strong>1 min</strong></td></tr><tr><td>Live</td><td><em>Burst</em></td><td><strong>50</strong> (per endpoint)</td><td><strong>10 secs</strong></td></tr><tr><td>Test</td><td><em>Burst</em></td><td><strong>25</strong> (per endpoint)</td><td><strong>10 secs</strong></td></tr></tbody></table>

## Response headers

You can get additional information you can use to avoid getting HTTP `429 Too many requests` [errors](/core/handling-errors) or to understand why your calls are being blocked by inspecting some specific headers included in the response:

| Header                      | Description                                                                                             |
| --------------------------- | ------------------------------------------------------------------------------------------------------- |
| **`X-Ratelimit-Limit`**     | The maximum number of requests allowed in the sliding time window.                                      |
| **`X-Ratelimit-Interval`**  | The total duration of the sliding time window (in seconds).                                             |
| **`X-Ratelimit-Remaining`** | The number of allowed requests remaining in the current time window (`0` in case of HTTP `429` errors). |

{% hint style="info" %}
The information in the headers above (number of requests, time window duration, etc.) refers to the *Average* [limit type](#other-endpoints) only.
{% endhint %}


# Handling errors

The complete list of response codes

Commerce Layer uses [HTTP response codes](https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) to show the success or failure of an API request.

* Codes in the `2xx` range indicate success.
* Codes in the `4xx` range indicate an error that failed given the information provided (e.g. bad request, failed validation, or authentication).
* Codes in the `5xx` range indicate an unhandled error (these are rare and should never happen).

| Code      |                          | Description                                                                                                                                      |
| --------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`200`** | `OK`                     | The request was successfully processed and everything worked as expected.                                                                        |
| **`201`** | `Created`                | The request was successfully processed and a new resource was created.                                                                           |
| **`204`** | `No content`             | The request was successfully processed and an existing resource was deleted.                                                                     |
| **`400`** | `Bad request`            | The request was unacceptable, often due to sending an unsupported parameter ([see example](#400-bad-request)).                                   |
| **`401`** | `Unauthorized`           | The access token was not present in the request, was expired, or didn't have enough permissions.                                                 |
| **`404`** | `Not found`              | The requested resource was not found, often due to a wrong resource's ID ([see example](#404-not-found)).                                        |
| **`405`** | `Method not allowed`     | The request method is known by the server but has been disabled and cannot be used.                                                              |
| **`406`** | `Not acceptable`         | The **Accept** header was not correctly set to `application/vnd.api+json`                                                                        |
| **`409`** | `Record not unique`      | The performed operation violates a unique constraint. You can safely ignore this warning.                                                        |
| **`415`** | `Unsupported media type` | The **Content-type** header was not correctly set to `application/vnd.api+json`                                                                  |
| **`422`** | `Unprocessable entity`   | The request body was well-formed but contains semantical errors, often due to validation constraints ([see example](#422-unprocessable-entity)). |
| **`423`** | `Locked`                 | The resource could not be deleted due to integrity constraints.                                                                                  |
| **`429`** | `Too many requests`      | The request was not accepted because you hit one of the [rate limits](/core/rate-limits).                                                        |
| **`500`** | `Internal server error`  | Something went wrong on our end and is being investigated by our engineers.                                                                      |

### The error object

All the `4xx` responses include an error object in the response body. The object contains the list of `errors` with some extra information.

{% hint style="warning" %}
Correct error handling is important. We recommend writing code that gracefully handles all possible API exceptions.
{% endhint %}

### Examples

#### 401 Unauthorized

{% tabs %}
{% tab title="Request" %}
The following request tries to retrieve (with sales channel API credentials) an SKU that's not *sellable* in the market the app has in scope (i.e. an SKU that doesn't have a price in one of the market's price list and at least one stock item in one of the market's stock location):

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/skus/BjwqSyPrKn' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
The API responds with a `401 Unauthorized` status code and returns a `UNAHUTORIZED` error:

```json
{
  "errors": [
    {
      "title": "Access denied",
      "detail": "You are not authorized to perform this action on the requested resource.",
      "code": "UNAUTHORIZED",
      "status": "401"
    }
  ]
}
```

{% endtab %}
{% endtabs %}

#### 422 Unprocessable Entity

{% tabs %}
{% tab title="Request" %}
The following request tries to update the quantity of a line item with an out-of-range value:

```shell
curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/line_items/saDFGhjkLZ' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "line_items",
      "id": "saDFGhjkLZ",
      "attributes": {
        "quantity": 100
      }
    }
  }'
```

{% endtab %}

{% tab title="Response" %}
The API responds with a `422 Unprocessable Entity` status code and returns a `VALIDATION_ERROR`:

```json
{
  "errors": [
    {
      "title": "must be less than or equal to 10",
      "detail": "quantity - must be less than or equal to 10",
      "code": "VALIDATION_ERROR",
      "source": {
        "pointer": "/data/attributes/quantity"
      },
      "status": "422",
      "meta": {
        "error": "less_than_or_equal_to",
        "value": 100,
        "count": 10
      }
    }
  ]
}
```

{% endtab %}
{% endtabs %}

#### 400 Bad Request

{% tabs %}
{% tab title="Request" %}
The following request tries to update a price but the ID in the URL does not match the one in the body:

```shell
curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/prices/yzkWXfgHQS' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
      "type": "prices",
      "id": "YZkWXgfQHS",
      "attributes": {
        "amount_cents": 4900
      }
    }
  }'
```

{% endtab %}

{% tab title="Response" %}
The API responds with a `400 Bad Request` status code and returns a `KEY_NOT_INCLUDED_IN_URL` error:

```json
{
  "errors": [
    {
      "title": "Key is not included in URL",
      "detail": "The URL does not support the key 10272",
      "code": "KEY_NOT_INCLUDED_IN_URL",
      "status": "400"
    }
  ]
}
```

{% endtab %}
{% endtabs %}

#### 404 Not Found

{% tabs %}
{% tab title="Request" %}
The following request tries to fetch a non-existing SKU:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/skus/XxYyZzKkJj' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
The API responds with a `404 Not Found` status code and returns a `RECORD_NOT_FOUND` error:

```json
{
  "errors": [
    {
      "title": "Record not found",
      "detail": "The requested resource was not found. Please double-check the resource id.",
      "code": "RECORD_NOT_FOUND",
      "status": "404"
    }
  ]
}
```

{% endtab %}
{% endtabs %}


# Real-time webhooks

The complete list of supported events for each resource

Commerce Layer provides a [webhook](https://en.wikipedia.org/wiki/Webhook) mechanism to react to specific events in real-time.

To subscribe to one (or more) of those events you need to [create](/core-api-reference/webhooks/create) the related webhook(s). Each time a subscribed event occurs, we trigger a `POST` request to the endpoint that you specified in the webhook's `callback_url` field. The request contains a JSON payload in the same format that you get when fetching the same resource through the REST API.

{% content-ref url="/pages/-LgRddsws89GnGAhaAll" %}
[Fetching resources](/core/fetching-resources)
{% endcontent-ref %}

For each resource, you can also configure the related resources that should be included in the request body. The relationships will be set as the resource `include` query parameter.

{% hint style="info" %}
When a `.tagged` event is triggered, the related tag(s) are automatically included in the callback's payload, as relationships of the tagged resource.
{% endhint %}

{% content-ref url="/pages/-LgSPUp0C3I-BB8HOD9M" %}
[Including associations](/core/including-associations)
{% endcontent-ref %}

{% hint style="info" %}
When a `.destroy` event is triggered the resource payload sent to the webhook endpoint is simplified — since the reference resource is deleted at the time the event is fired, only the destroyed resource's `id` is valorized, while all of the other attributes and included relationships are `null`.
{% endhint %}

{% content-ref url="/pages/-LgSrWoznG0KnaZkkuSK" %}
[Deleting resources](/core/deleting-resources)
{% endcontent-ref %}

When you create a new webhook, a **shared secret** is generated. It will be used each time the webhook is fired to sign the payload. The related signature will be stored in the **`X-CommerceLayer-Signature`** header so that you can verify the callback authenticity and consider it reliable.

{% content-ref url="/pages/-MIOPl2nMJoIW7dGQnpO" %}
[Callbacks security](/core/callbacks-security)
{% endcontent-ref %}

{% hint style="success" %}
If you need to receive real-time notifications for any changes to the resources exposed by our platform, consider also to leverage our SSE-based [event stream hub](/core/event-stream-hub).
{% endhint %}

## Supported events

You can find here below the complete list of all the topics `{{resource}}.{{event}}` you can monitor:

| Topic                                          | Trigger                                                                                                                                                                    |
| ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| addresses.**tagged**                           | One or more existing tags are associated with an address.                                                                                                                  |
| authorizations.**create**                      | An authorization transaction is created.                                                                                                                                   |
| authorizations.**succeeded**                   | An authorization transaction has been successfully executed.                                                                                                               |
| authorizations.**failed**                      | An authorization transaction failed its execution.                                                                                                                         |
| avalara\_accounts.**invoice\_committed**       | Invoice for Avalara account gets committed.                                                                                                                                |
| avalara\_accounts.**invoice\_refunded**        | Invoice for Avalara account gets refunded.                                                                                                                                 |
| avalara\_accounts.**invoice\_commit\_failed**  | Commit for Avalara account invoice failed.                                                                                                                                 |
| avalara\_accounts.**invoice\_refund\_failed**  | Refund for Avalara account invoice failed.                                                                                                                                 |
| bundles.**tagged**                             | One or more existing tags are associated with a bundle.                                                                                                                    |
| buy\_x\_pay\_y\_promotions.**create**          | A buy X pay Y promotion is created.                                                                                                                                        |
| buy\_x\_pay\_y\_promotions.**tagged**          | One or more existing tags are associated with a buy X pay Y promotion.                                                                                                     |
| buy\_x\_pay\_y\_promotions.**destroy**         | An existing `buy_x_pay_y_promotions` object is deleted.                                                                                                                    |
| captures.**create**                            | A capture transaction is created.                                                                                                                                          |
| captures.**succeeded**                         | A capture transaction has been successfully executed.                                                                                                                      |
| captures.**failed**                            | A capture transaction failed its execution.                                                                                                                                |
| cleanups.**create**                            | A new cleanup is created.                                                                                                                                                  |
| cleanups.**start**                             | An existing cleanup status is set to `in_progress`.                                                                                                                        |
| cleanups.**complete**                          | An existing cleanup status is set to `completed`.                                                                                                                          |
| cleanups.**interrupt**                         | An existing cleanup status is set to `interrupted`.                                                                                                                        |
| cleanups.**destroy**                           | An existing `clenups` object is deleted.                                                                                                                                   |
| coupons.**tagged**                             | One or more existing tags are associated with a coupon.                                                                                                                    |
| customer\_addresses.**create**                 | A new customer address is created.                                                                                                                                         |
| customer\_addresses.**destroy**                | An existing `customer_addresses` object is deleted.                                                                                                                        |
| customer\_password\_resets.**create**          | A customer password reset process is initiated.                                                                                                                            |
| customer\_password\_resets.**destroy**         | An existing `customer_password_resets` object is deleted.                                                                                                                  |
| customer\_password\_resets.**reset\_password** | A customer password is reset.                                                                                                                                              |
| customer\_subscriptions.**create**             | A new customer subscription is created.                                                                                                                                    |
| customer\_subscriptions.**destroy**            | An existing `customer_subscriptions` object is deleted.                                                                                                                    |
| customers.**create**                           | A new customer is created.                                                                                                                                                 |
| customers.**acquired**                         | An existing customer status is set to `acquired`.                                                                                                                          |
| customers.**repeat**                           | An existing customer status is set to `repeat`.                                                                                                                            |
| customers.**create\_password**                 | A new password for a customer is created.                                                                                                                                  |
| customers.**metadata\_update**                 | An existing customer metatdata are updated.                                                                                                                                |
| customers.**tagged**                           | One or more existing tags are associated with a customer.                                                                                                                  |
| customers.**destroy**                          | An existing `customers` object is deleted.                                                                                                                                 |
| customers.**anonymization\_started**           | A customer anonymization request has been taken over.                                                                                                                      |
| customers.**anonymization\_completed**         | A customer anonymization process has been successfully completed.                                                                                                          |
| customers.**anonymization\_failed**            | A customer anonymization process failed.                                                                                                                                   |
| customers.**anonymization\_cancelled**         | An ongoing customer anonymization process (not yet completed) has been cancelled.                                                                                          |
| exports.**create**                             | A new export is created.                                                                                                                                                   |
| exports.**start**                              | An existing export status is set to `in_progress`.                                                                                                                         |
| exports.**complete**                           | An existing export status is set to `completed`.                                                                                                                           |
| exports.**interrupt**                          | An existing export status is set to `interrupted`.                                                                                                                         |
| exports.**destroy**                            | An existing `exports` object is deleted.                                                                                                                                   |
| external\_promotions.**create**                | An external promotion is created.                                                                                                                                          |
| external\_promotions.**tagged**                | One or more existing tags are associated with an external promotion.                                                                                                       |
| external\_promotions.**destroy**               | An existing `external_promotions` object is deleted.                                                                                                                       |
| external\_promotions.**failed**                | An existing external promotion failed to apply.                                                                                                                            |
| fixed\_amount\_promotions.**create**           | A fixed amount promotion is created.                                                                                                                                       |
| fixed\_amount\_promotions.**tagged**           | One or more existing tags are associated with a fixed amount promotion.                                                                                                    |
| fixed\_amount\_promotions.**destroy**          | An existing `fixed_amount_promotions` object is deleted.                                                                                                                   |
| fixed\_price\_promotions.**create**            | A fixed price promotion is created.                                                                                                                                        |
| fixed\_price\_promotions.**tagged**            | One or more existing tags are associated with a fixed price promotion.                                                                                                     |
| fixed\_price\_promotions.**destroy**           | An existing `fixed_price_promotions` object is deleted.                                                                                                                    |
| flex\_promotions.**create**                    | A flex promotion is created.                                                                                                                                               |
| flex\_promotions.**tagged**                    | One or more existing tags are associated with a flex promotion.                                                                                                            |
| flex\_promotions.**destroy**                   | An existing `flex_promotions` object is deleted.                                                                                                                           |
| free\_gift\_promotions.**create**              | A free gift promotion is created.                                                                                                                                          |
| free\_gift\_promotions.**tagged**              | One or more existing tags are associated with a free gift promotion.                                                                                                       |
| free\_gift\_promotions.**destroy**             | An existing `free_gift_promotions` object is deleted.                                                                                                                      |
| free\_shipping\_promotions.**create**          | A free shipping promotion is created.                                                                                                                                      |
| free\_shipping\_promotions.**tagged**          | One or more existing tags are associated with a free shipping promotion.                                                                                                   |
| free\_shipping\_promotions.**destroy**         | An existing `free_shipping_promotions` object is deleted.                                                                                                                  |
| gift\_cards.**create**                         | A new gift card is created.                                                                                                                                                |
| gift\_cards.**purchase**                       | An existing gift card is purchased.                                                                                                                                        |
| gift\_cards.**activate**                       | An existing gift card status is set to `active`.                                                                                                                           |
| gift\_cards.**deactivate**                     | An active gift card status is set to `inactive`.                                                                                                                           |
| gift\_cards.**redeem**                         | An existing gift card status is set to `redeemed`.                                                                                                                         |
| gift\_cards.**use**                            | A gift card is used to pay for an order.                                                                                                                                   |
| gift\_cards.**tagged**                         | One or more existing tags are associated with a gift card.                                                                                                                 |
| gift\_cards.**destroy**                        | An existing `gift_cards` object is deleted.                                                                                                                                |
| imports.**create**                             | A new import is created.                                                                                                                                                   |
| imports.**start**                              | An existing import status is set to `in_progress`.                                                                                                                         |
| imports.**complete**                           | An existing import status is set to `completed`.                                                                                                                           |
| imports.**interrupt**                          | An existing import status is set to `interrupted`.                                                                                                                         |
| imports.**destroy**                            | An existing `imports` object is deleted.                                                                                                                                   |
| in\_stock\_subscriptions.**create**            | A new in-stock subscription is created.                                                                                                                                    |
| in\_stock\_subscriptions.**activate**          | An existing in-stock subscription status is set to `active`.                                                                                                               |
| in\_stock\_subscriptions.**deactivate**        | An existing in-stock subscription status is set to `inactive`.                                                                                                             |
| in\_stock\_subscriptions.**notify**            | An existing in-stock subscription status is set to `notified`.                                                                                                             |
| in\_stock\_subscriptions.**destroy**           | An existing `in_stock_subscriptions` object is deleted.                                                                                                                    |
| line\_items.**tagged**                         | One or more existing tags are associated with a line item.                                                                                                                 |
| line\_item\_options.**tagged**                 | One or more existing tags are associated with a line item option.                                                                                                          |
| orders.**create**                              | A new order is created.                                                                                                                                                    |
| orders.**draft**                               | An existing order status is set to `draft`.                                                                                                                                |
| orders.**pending**                             | An existing order status is set to `pending`.                                                                                                                              |
| orders.**placing**                             | An existing order status is set to `placing`.                                                                                                                              |
| orders.**place**                               | An existing order status is set to `placed`.                                                                                                                               |
| orders.**start\_editing**                      | An existing order status is moved from `placed` to `editing`.                                                                                                              |
| orders.**stop\_editing**                       | An existing order status is moved back from `editing` to `placed`.                                                                                                         |
| orders.**approve**                             | An existing order status is set to `approved`.                                                                                                                             |
| orders.**cancel**                              | An existing order status is set to `cancelled`.                                                                                                                            |
| orders.**authorize**                           | An existing order payment status is set to `authorized` or `partially_authorized` (in the latter case, multiple events are fired until the authorization balance is zero). |
| orders.**void**                                | An existing order payment status is set to `voided` or `partially_voided` (in the latter case, multiple events are fired until the void balance is zero).                  |
| orders.**pay**                                 | An existing order payment status is set to `paid` or `partially_paid` (in the latter case, multiple events are fired until the capture balance is zero).                   |
| orders.**refund**                              | An existing order payment status is set to `refunded` or `partially_refunded` (in the latter case, multiple events are fired until the refund balance is zero).            |
| orders.**start\_fulfilling**                   | An existing order fulfillment status is set to `in_progress`.                                                                                                              |
| orders.**cancel\_fulfilling**                  | An existing order with fulfillment status `in_progress` is cancelled.                                                                                                      |
| orders.**fulfill**                             | An existing order fulfillment status is set to `fulfilled`.                                                                                                                |
| orders.**rebuild\_shipments**                  | An existing order's shipments are rebuilt.                                                                                                                                 |
| orders.**create\_subscriptions**               | An order subscription automatic generation from line items with frequency is triggered.                                                                                    |
| orders.**cancel\_subscriptions**               | An order subscription automatic cancellation due to the related source order cancellation has started.                                                                     |
| orders.**tagged**                              | One or more existing tags are associated with an order.                                                                                                                    |
| orders.**tax\_calculation\_failed**            | Tax calculation failed for an existing order.                                                                                                                              |
| orders.**destroy**                             | An existing `orders` object is deleted.                                                                                                                                    |
| order\_copies.**create**                       | A new order copy is created.                                                                                                                                               |
| order\_copies.**destroy**                      | An existing orders `order_copies` object is deleted.                                                                                                                       |
| order\_copies.**start**                        | An existing order copy started.                                                                                                                                            |
| order\_copies.**fail**                         | An existing order copy failed.                                                                                                                                             |
| order\_copies.**complete**                     | An existing order copy has been completed.                                                                                                                                 |
| order\_subscriptions.**create**                | A new order subscription is created.                                                                                                                                       |
| order\_subscriptions.**destroy**               | An existing orders `order_subscriptions` object is deleted.                                                                                                                |
| order\_subscriptions.**activate**              | An existing order subscription has been activated.                                                                                                                         |
| order\_subscriptions.**deactivate**            | An existing order subscription has been deactivated.                                                                                                                       |
| order\_subscriptions.**cancel**                | An existing order subscription has been cancelled.                                                                                                                         |
| order\_subscriptions.**last\_run\_failed**     | The last run of an existing order subscription has failed.                                                                                                                 |
| order\_subscriptions.**last\_run\_succeeded**  | The last run of an existing order subscription has succeeded.                                                                                                              |
| order\_subscriptions.**renewal**               | An existing order subscription is going to be renewed within the specified renewal alert period.                                                                           |
| parcels.**create**                             | A new parcel is created.                                                                                                                                                   |
| parcels.**destroy**                            | An existing orders `parcels` object is deleted.                                                                                                                            |
| parcels.**pre\_transit**                       | An existing parcel tracking status is set to `pre_transit`.                                                                                                                |
| parcels.**in\_transit**                        | An existing parcel tracking status is set to `in_transit`.                                                                                                                 |
| parcels.**out\_for\_delivery**                 | An existing parcel tracking status is set to `out_for_delivery`.                                                                                                           |
| parcels.**delivered**                          | An existing parcel tracking status is set to `delivered`.                                                                                                                  |
| parcels.**shipped**                            | An existing parcel tracking status is set to `shipped`.                                                                                                                    |
| parcels.**available\_for\_pickup**             | An existing parcel tracking status is set to `available_for_pickup`.                                                                                                       |
| parcels.**booked**                             | An existing parcel tracking status is set to `booked`.                                                                                                                     |
| parcels.**return\_to\_sender**                 | An existing parcel tracking status is set to `return_to_sender`.                                                                                                           |
| parcels.**cancelled**                          | An existing parcel tracking status is set to `cancelled`.                                                                                                                  |
| parcels.**failure**                            | An existing parcel tracking status is set to `failure`.                                                                                                                    |
| percentage\_discount\_promotions.**create**    | A new percentage discount promotion is created.                                                                                                                            |
| percentage\_discount\_promotions.**tagged**    | One or more existing tags are associated with a percentage discount promotion.                                                                                             |
| percentage\_discount\_promotions.**destroy**   | An existing `percentage_discount_promotions` object is deleted.                                                                                                            |
| price\_frequency\_tiers.**create**             | A new price frequency tier is created.                                                                                                                                     |
| price\_frequency\_tiers.**destroy**            | An existing `price_frequency_tiers` object is deleted.                                                                                                                     |
| price\_list\_schedulers.**activated**          | An existing price list scheduler has become active.                                                                                                                        |
| price\_list\_schedulers.**expired**            | A previously active price list scheduler has expired.                                                                                                                      |
| price\_volume\_tiers.**create**                | A new price volume tier is created.                                                                                                                                        |
| price\_volume\_tiers.**destroy**               | An existing `price_volume_tiers` object is deleted.                                                                                                                        |
| promotions.**create**                          | A new promotion is created (regardless of the type).                                                                                                                       |
| promotions.**tagged**                          | One or more existing tags are associated with a promotion (regardless of the type).                                                                                        |
| promotions.**destroy**                         | An existing `promotions` object is deleted.                                                                                                                                |
| recurring\_order\_copies.**create**            | A new recurring order copy is created.                                                                                                                                     |
| recurring\_order\_copies.**destroy**           | An existing orders `recurring_order_copies` object is deleted.                                                                                                             |
| recurring\_order\_copies.**start**             | An existing recurring order copy started.                                                                                                                                  |
| recurring\_order\_copies.**fail**              | An existing recurring order copy failed.                                                                                                                                   |
| recurring\_order\_copies.**complete**          | An existing recurring order copy has been completed.                                                                                                                       |
| refunds.**create**                             | A refund transaction is created.                                                                                                                                           |
| refunds.**succeeded**                          | A refund transaction has been successfully executed.                                                                                                                       |
| refunds.**failed**                             | A refund transaction failed its execution.                                                                                                                                 |
| returns.**create**                             | A new return is created.                                                                                                                                                   |
| returns.**cancel**                             | An existing return status is set to `cancelled`.                                                                                                                           |
| returns.**request**                            | An existing return status is set to `requested`.                                                                                                                           |
| returns.**pending**                            | An existing return status is set to `pending`.                                                                                                                             |
| returns.**approve**                            | An existing return status is set to `approved`.                                                                                                                            |
| returns.**reject**                             | An existing return status is set to `rejected`.                                                                                                                            |
| returns.**ship**                               | An existing return status is set to `shipped`.                                                                                                                             |
| returns.**receive**                            | An existing return status is set to `received`.                                                                                                                            |
| returns.**refund**                             | An existing return status is set to `refunded`.                                                                                                                            |
| returns.**restock**                            | An existing return's line items are restocked.                                                                                                                             |
| returns.**tagged**                             | One or more existing tags are associated with a return.                                                                                                                    |
| returns.**destroy**                            | An existing `returns` object is deleted.                                                                                                                                   |
| shipments.**tagged**                           | One or more existing tags are associated with a shipment.                                                                                                                  |
| shipments.**upcoming**                         | An existing shipment status is set to `upcoming`.                                                                                                                          |
| shipments.**cancel**                           | An existing shipment status is set to `cancelled`.                                                                                                                         |
| shipments.**on\_hold**                         | An existing shipment status is set to `on_hold`.                                                                                                                           |
| shipments.**picking**                          | An existing shipment status is set to `picking`.                                                                                                                           |
| shipments.**packing**                          | An existing shipment status is set to `packing`.                                                                                                                           |
| shipments.**ready\_to\_ship**                  | An existing shipment status is set to `ready_to_ship`.                                                                                                                     |
| shipments.**ship**                             | An existing shipment status is set to `shipped`.                                                                                                                           |
| shipments.**deliver**                          | An existing shipment status is set to `delivered`.                                                                                                                         |
| shipping\_weight\_tiers.**create**             | A new shipping weight tier is created.                                                                                                                                     |
| shipping\_weight\_tiers.**destroy**            | An existing `shipping_weight_tiers` object is deleted.                                                                                                                     |
| skus.**tagged**                                | One or more existing tags are associated with an SKU.                                                                                                                      |
| sku\_options.**tagged**                        | One or more existing tags are associated with an SKU option.                                                                                                               |
| stock\_transfers.**create**                    | A new stock transfer is created.                                                                                                                                           |
| stock\_transfers.**upcoming**                  | An existing stock transfer status is set to `upcoming`.                                                                                                                    |
| stock\_transfers.**picking**                   | An existing stock transfer status is set to `picking`.                                                                                                                     |
| stock\_transfers.**in\_transit**               | An existing stock transfer status is set to `in_transit`.                                                                                                                  |
| stock\_transfers.**complete**                  | An existing stock transfer status is set to `completed`.                                                                                                                   |
| stock\_transfers.**cancel**                    | An existing stock transfer status is set to `cancelled`                                                                                                                    |
| stock\_transfers.**on\_hold**                  | An existing stock transfer status is set to `on_hold`.                                                                                                                     |
| stock\_transfers.**destroy**                   | An existing `stock_transfers` object is deleted                                                                                                                            |
| transactions.**create**                        | A new transaction is created (regardless of the type).                                                                                                                     |
| transactions.**refused**                       | A successful transaction has been refused by the payment gateway (i.e. the transaction `succeeded` attribute has changed from `true` to `false`).                          |
| voids.**create**                               | A void transaction is created.                                                                                                                                             |
| voids.**succeeded**                            | A void transaction has been successfully executed.                                                                                                                         |
| voids.**failed**                               | A void transaction failed its execution.                                                                                                                                   |

{% hint style="info" %}
The topic of the the event the triggered the request to the callback URL is also stored in the **`X-CommerceLayer-Topic`** [header](/core/external-resources#request-headers) of the request.
{% endhint %}

### Webhooks and imports

During [imports](/core/importing-resources) all of the real-time webhooks are **disabled** with the exception of some of the ones related to order status change events, namely:

* `orders.place`
* `orders.approve`
* `orders.cancel`
* `orders.authorize`
* `orders.void`
* `orders.pay`
* `orders.refund`
* `orders.start_fulfilling`
* `orders.cancel_fulfilling`
* `orders.fulfill`

{% hint style="warning" %}
In case you need to leverage all the other real-time events you have to create/update resources via the related API endpoints.&#x20;
{% endhint %}

## Retriggering events

Events are automatically triggered at creation time, notifying all listening webhooks. If, for some reason, you want to force the firing of an existing event manually, you can leverage the related trigger attribute on the [event](/core-api-reference/events#retriggering-events) resource — the event will be immediately triggered, regardless of its uniqueness.

## Responding to webhook callbacks

The endpoint listening for webhooks has **5 seconds** to respond with a **`2xx`** (usually `200` ) response code, acknowledging a successful delivery. If the request times out or gets a response with a status code other than `2xx`, it is considered failed.

## Handling webhook failures

If a webhook fails (whatever the reason) Commerce Layer tries to fire it again up to **10 times**. After **30 consecutive failures** (retry failures included) no further calls to the related endpoint are made and the webhook has to be reset.

{% hint style="info" %}
To let you properly handle this scenario and inspect the reasons for the failure, after **5** consecutive non-successful attempts a communication is sent to the owner and all the admins of the organization.
{% endhint %}


# Event stream hub

Unified SSE-based stream of the Core API resource lifecycle events, with support for time-based and resource-based replay

In addition to a [webhook-based](/core/real-time-webhooks) event handling, Commerce Layer also provides a [Change Data Capture (CDC)](https://en.wikipedia.org/wiki/Change_data_capture) system to capture and track changes to data instantly.

Leveraging [Server-Sent Events (SSE)](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events), we enable clients to receive real-time notifications for [any changes](#supported-events) to the resources exposed by our platform (e.g. SKUs, orders, customers, etc.) just by subscribing to an event stream and consume updates as they happen.

{% hint style="danger" %}
The Stream Hub is in **beta**, and it's available only to our **enterprise** customers who [enable](#how-to-enable-the-stream-hub) it, meaning that only the changes to resources belonging to enterprise organizations with this feature enabled are pushed to the event stream. At the moment, there are no time limits on the event history storage. We will use this beta period before the official release to run load tests and determine how long to retain past event information.
{% endhint %}

SSE provides a lightweight, one-way communication channel from the server to the client over a single long-lived HTTP connection. It’s ideal for real-time feeds, system monitoring, or keeping local caches in sync with backend state. The protocol uses standard **HTTP** and the `text/event-stream` content type to send a stream of **UTF-8** encoded messages from the server to the client. Once connected, the client listens for incoming messages without needing to poll until the connection is closed.

{% hint style="warning" %}
If, for any reason, the connection to the stream hub drops before being intentionally closed, ensure that your stream reader app handles a reconnection/retry policy. Keep in mind that the disconnected stream is considered stale after 5 secs, so you cannot request a new real-time stream until **5 secs** after the connection drop.
{% endhint %}

Once reconnected, any event message that you hadn't received yet but the consumers had already started to process in the last **30 mins** is re-pushed to the live stream. Previous messages (dating back over half an hour from the disconnection) can always be [recovered](#event-recovery-and-replay-by-resource) by passing a specific time frame to the `/replay` endpoint of the stream hub.

{% hint style="info" %}
Both the real-time stream and the replay stream show only the events related to the [environment](/core/api-specification#environments) (*test* or *live*) associated with the integration token used to [authenticate the API call](#connecting-to-the-event-stream).
{% endhint %}

## Supported events

Currently, the list of events pushed to the Commerce Layer Stream Hub includes all the **create**, **update**, and **delete** operations on [any Core API resource](https://docs.commercelayer.io/core-api-reference/).&#x20;

<table><thead><tr><th width="229.7890625">Event type</th><th>Description</th></tr></thead><tbody><tr><td><strong><code>heartbeat</code></strong></td><td>Checks the connection to the stream every <strong>10 secs</strong>.</td></tr><tr><td><strong><code>create</code></strong></td><td>A new resource has been created.</td></tr><tr><td><strong><code>update</code></strong></td><td>An existing resource has been updated.</td></tr><tr><td><strong><code>destroy</code></strong></td><td>An existing resource has been destroyed.</td></tr><tr><td><strong><code>anonymization_request</code></strong></td><td>The anonymization of a customer's data has been requested (available for the customer resource only).</td></tr><tr><td><strong><code>anonymization_cancel</code></strong></td><td>An ongoing customer's data anonymization request has been revoked (available for the customer resource only).</td></tr></tbody></table>

{% hint style="success" %}
In the near future, more information will be added to the stream (e.g. external payloads so as to be able to track events like: webhooks received from payment gateways, API calls made to third-party services, other side-effects tied to a specific resource, etc.).
{% endhint %}

## Connecting to the event stream

To start a connection to the Commerce Layer Stream Hub, you just need to send a GET request to the following endpoint:

```http
https://stream.commercelayer.io/{{your_domain}}
```

Where `{{your_domain}}` is the unique subdomain of your Commerce Layer organization.

{% hint style="warning" %}
Any call to the stream endpoints must be [authenticated](/core/authentication/client-credentials) using [integration](/core/api-credentials#integration) API credentials.
{% endhint %}

{% hint style="info" %}
This endpoint automatically acknowledges messages as they are streamed to the client.
{% endhint %}

Once connected, each message in the stream follows a simple format:

<table><thead><tr><th width="230.12109375">Key</th><th>Description</th></tr></thead><tbody><tr><td><strong><code>event</code></strong></td><td>The <a href="#supported-events">type of event</a>.</td></tr><tr><td><strong><code>id</code></strong></td><td>A unique identifier for the event.</td></tr><tr><td><strong><code>data</code></strong></td><td>A JSON object representing the resource and highlighting the delta of the change (or just a timestamp in case of heartbeats).</td></tr></tbody></table>

{% hint style="info" %}
The `data` object of each event message (other than the heartbeats) basically contains the whole related [event store resource object](/core-api-reference/event_stores/object), providing information about the type of change, the affected resource, the object changes payload, the actor who triggered the change, the exact timestamp of the change, and more (see the response in the [example](#example) below).
{% endhint %}

### Example

{% tabs %}
{% tab title="Request" %}
The following request starts a connection to the event stream of the enterprise organization with slug `my-org`:

```sh
curl -g -X GET \
  'https://stream.commercelayer.io/my-org' \
  -H 'Authorization: Bearer your-access-token' 
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a continuous type-based event stream:

<pre class="language-http"><code class="lang-http"><strong>event: heartbeat
</strong>id: 1753710752696-0
data: {
  "event": "heartbeat",
  "timestamp": "2025-07-28T13:52:02Z"
}

<strong>event: heartbeat
</strong>id: 1753710752697-0
data: {
  "event": "heartbeat",
  "timestamp": "2025-07-28T13:52:12Z"
}

<strong>event: create
</strong>id: 1753710752698-0
data: {
  "event": "create",
  "resource_type": "skus",
  "resource_id": "CALKSWJxwW",
  "organization_id": "XMlEOFrjdf",
  "payload": {
    "code": {
      "from": null,
      "to": "MMOUSEMUG"
    },
    "name": {
      "from": null,
      "to": "Mickey Mouse Mug"
    },
      "description": {
      "from": null,
      "to": "A Mickey Mouse branded mug."
    },
    "pieces_per_pack": {
      "from": null,
      "to": 1
    },
    "weight": {
      "from": null,
      "to": 400.0
    },
    "unit_of_weight": {
      "from": null,
      "to": "gr"
    },
    "hs_tariff_number": {
      "from": null,
      "to": ""
    },
    "id": {
      "from": null,
      "to": 42231
    },
    "created_at": {
      "from": null,
      "to": "2025-07-28T13:52:22.000Z"
    },
    "updated_at": {
      "from": null,
      "to": "2025-07-28T13:52:22.000Z"
    }
  },
  "ip_address": "93.21.228.116",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
  "uuid": "45ff6e19293a2887ss78fde16d143ad8659a1dd1a6b0fbe6e2d3bac103c02cfcc",
  "test": false,
  "created_at": "2025-07-28T13:52:22.000Z",
  "updated_at": "2025-07-28T13:52:22.000Z",
  "who": {
    "application": {
      "id": "FKjbrtebqV",
      "client_id": "app_Cl13NTYd-KOwFhtKMvQIvj-KZY",
      "kind": "skus",
      "public": false
    },
    "owner": {
      "id": "sRmwmSGRfg",
      "type": "User",
      "email": "john@example.com",
      "first_name": "John",
      "last_name": "Doe"
    }
  }
}

<strong>event: heartbeat
</strong>id: 1753710752699-0
data: {
  "event": "heartbeat",
  "timestamp": "2025-07-28T13:52:32Z"
}

<strong>event: heartbeat
</strong>id: 1753710752699-0
data: {
  "event": "heartbeat",
  "timestamp": "2025-07-28T13:52:42Z"
}

<strong>event: destroy
</strong>id: 1753710752700-0
data: {
  "event": "destroy",
  "resource_type": "skus",
  "resource_id": "CALKSWJxwW",
  "organization_id": "XMlEOFrjdf",
  "payload": {
    "code": {
      "from": "MMOUSEMUG",
      "to": null
    },
    "name": {
      "from": "Mickey Mouse Mug",
      "to": null
    },
    "description": {
      "from": "A Mickey Mouse branded mug.",
      "to": null
    },
    "pieces_per_pack": {
      "from": 1,
      "to": null
    },
    "weight": {
      "from": 400.0,
      "to": null
    },
    "unit_of_weight": {
      "from": "gr",
      "to": null
    },
    "hs_tariff_number": {
      "from": "",
      "to": null
    },
    "do_not_ship": {
      "from": false,
      "to": null
    },
    "do_not_track": {
      "from": false,
      "to": null
    },
    "id": {
      "from": 42231,
      "to": null
    },
    "created_at": {
      "from": "2025-07-28T13:52:52.000Z",
      "to": null
    },
    "updated_at": {
      "from": "2025-07-28T13:52:52.000Z",
      "to": null
    },
    "metadata": {
      "from": {},
      "to": null
    }
  },
  "ip_address": "93.21.228.116",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
  "uuid": "f416778f7043a81266rf70e0a9f9337cf7508d32a1dccc7001f1826dc7150912",
  "test": false,
  "created_at": "2025-07-28T13:52:52.000Z",
  "updated_at": "2025-07-28T13:52:52.000Z",
  "who": {
    "application": {
      "id": "FKjbrtebqV",
      "client_id": "app_Cl13NTYd-KOwFhtKMvQIvj-KZY",
      "kind": "skus",
      "public": false
    },
    "owner": {
      "id": "sRmwmSGRfg",
      "type": "User",
      "email": "john@example.com",
      "first_name": "John",
      "last_name": "Doe"
    }
  }
}

<strong>event: heartbeat
</strong>id: 1753710752701-0
data: {
  "event": "heartbeat",
  "timestamp": "2025-07-28T13:53:02Z"
}

<strong>event: update
</strong>id: 1753710752702-0
data: {
  "event": "update",
  "resource_type": "skus",
  "resource_id": "WJoqSjzGjB",
  "organization_id": "XClEOFrjef",
    "payload": {
      "updated_at": {
        "from": "2025-07-29T15:22:20.884Z",
        "to": "2025-07-28T13:53:12.000Z"
      }
    },
  "ip_address": "93.45.228.116",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
  "uuid": "65bdc067600c4879c903c8252d4e03hhb75b818ca2464fa9217b4f0e755b45d9",
  "test": true,
  "created_at": "2025-07-28T13:53:12.000Z",
  "updated_at": "2025-07-28T13:53:12.000Z",
  "who": {
    "application": {
      "id": "DMjvdiebqM",
      "client_id": "myApp-Cl13nt-IDr-KOwFhtKMvQIvj-KZY",
      "kind": "skus",
      "public": false
    },
    "owner": {
      "id": "sCfwmSNRed",
      "type": "User",
      "email": "jane@example.com",
      "first_name": "Jane",
      "last_name": "Doe"
    }
  }
}

<strong>event: create
</strong>id: 1753710752703-0
data: {
  "event": "create",
  "resource_type": "events",
  "resource_id": "wXmBMUlxpL",
  "organization_id": "XMlEOFrjdf",
  "payload": {
    "name": {
      "from": null,
      "to": "skus.tagged"
    },
    "id": {
      "from": null,
      "to": 2422087
    },
    "created_at": {
      "from": null,
      "to": "2025-07-28T13:53:12.000Z"
    },
    "updated_at": {
      "from": null,
      "to": "2025-07-28T13:53:12.000Z"
    }
  },
  "ip_address": "93.45.228.116",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
  "uuid": "65bdc078600c4879c903c8252d4e03cca75b818ca2464fa9217b4f0e755b45d9",
  "test": true,
  "created_at": "2025-07-28T13:53:12.000Z",
  "updated_at": "2025-07-28T13:53:12.000Z",
  "who": {
    "application": {
      "id": "DMjvdiebqM",
      "client_id": "myApp-Cl13nt-IDr-KOwFhtKMvQIvj-KZY",
      "kind": "skus",
      "public": false
    },
    "owner": {
      "id": "sCfwmSNRed",
      "type": "User",
      "email": "jane@example.com",
      "first_name": "Jane",
      "last_name": "Doe"
    }
  }
}

<strong>event: heartbeat
</strong>id: 1753710752704-0
data: {
  "event": "heartbeat",
  "timestamp": "2025-07-28T13:53:22Z"
}

<strong>event: heartbeat
</strong>id: 1753710752705-0
data: {
  "event": "heartbeat",
  "timestamp": "2025-07-28T13:53:32Z"
}

...
        
</code></pre>

{% endtab %}
{% endtabs %}

## Event recovery and replay by resource

Along with the live stream, the Commerce Layer Stream Hub service offers an additional endpoint that queues a replay job to retrieve historical events:

```http
https://stream.commercelayer.io/{{your_domain}}/replay
```

This is useful for clients that were disconnected, are syncing a local store, or need to audit events over a given timeframe. The same endpoint can also be used to fetch the events related to a specific resource or to a set of specific instances of that resource.

{% hint style="warning" %}
The replay timeframe cannot exceed **7 days**.
{% endhint %}

The `/replay` endpoint accepts the desired timeframe, resource type, and optional resource IDs as query parameters:

<table><thead><tr><th width="166.921875">Query parameter</th><th width="106.6484375" data-type="checkbox">Required</th><th width="321.23046875">Description</th><th width="240.2890625">Example</th></tr></thead><tbody><tr><td><strong><code>date_from</code></strong></td><td>true</td><td>The <a href="https://www.iso.org/iso-8601-date-and-time-format.html">ISO8601</a> timestamp for the start of the replay window (YYYY-MM-DDTHH:MM:SSZ) — must be no more than 7 days before <code>date_to</code>, optional if you're passing <code>resource_id_in</code>.</td><td><code>2025-01-10T12:15:00Z</code></td></tr><tr><td><strong><code>date_to</code></strong></td><td>true</td><td>The <a href="https://www.iso.org/iso-8601-date-and-time-format.html">ISO8601</a> timestamp for the start of the replay window (YYYY-MM-DDTHH:MM:SSZ) — must be no more than 7 days after <code>date_from</code>, optional if you're passing <code>resource_id_in</code>.</td><td><code>2025-01-16T12:15:00Z</code></td></tr><tr><td><strong><code>resource_type_eq</code></strong></td><td>false</td><td>The type of resource for which you need to replay the event changes — required if you're passing <code>resource_id_in</code>.</td><td><code>skus</code></td></tr><tr><td><strong><code>resource_id_in</code></strong></td><td>false</td><td>A comma-separated list of IDs of the specified resource type (no space after the comma).</td><td><code>AYqPSwAqDW,WRfaDFdGeOK</code></td></tr></tbody></table>

The `/replay` endpoint also introduces two additional types of events to notify of the beginning and the completion of the replay stream:

<table><thead><tr><th width="229.7890625">Event type</th><th>Description</th></tr></thead><tbody><tr><td><strong><code>replay_started</code></strong></td><td>A replay stream has started.</td></tr><tr><td><strong><code>stream_complete</code></strong></td><td>A replay stream has been completed.</td></tr></tbody></table>

{% hint style="info" %}
Of course, being a replay, no heartbeat will show in the stream in this case.
{% endhint %}

### Examples

#### Replay by timeframe

{% tabs %}
{% tab title="Request" %}
The following request replays the events streamed within a specified time window:

```sh
curl -g -X GET \
  'https://stream.commercelayer.io/my-org/replay?date_from=2025-07-30T16:00:00Z&date_to=2025-07-31T16:30:00Z' \
  -H 'Authorization: Bearer your-access-token' 
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the event stream related to the specified time window:

<pre><code><strong>event: replay_started
</strong>id: 1753973120642-0
data: {
  "event": "replay_started",
  "timestamp": "2025-07-31T14:30:00Z"
}

<strong>event: create
</strong>id: 1753973120739-0
data: {
  "id": "1753971708673-0",
  "event": "create",
  "resource_type": "transactions",
  "resource_id": "GbwPUnYXnj",
  "organization_id": "XMlEOFrjdf",
  "payload": {
    "number": {
      "from": null,
      "to": "2662594/T/002"
    },
    "type": {
      "from": null,
      "to": "Authorization"
    },
    "currency_code": {
      "from": null,
      "to": "EUR"
    },
    "amount_cents": {
      "from": null,
      "to": "9900.0"
    },
    "succeeded": {
      "from": null,
      "to": false
    },
    "message": {
      "from": null,
      "to": "Pending"
    },
    "token": {
      "from": null,
      "to": "pay_gplxkwz7lghurncpzx4fv6zxny"
    },
    "gateway_transaction_id": {
      "from": null,
      "to": "pay_gplxkwz7lghurncpzx4fv6zxny"
    },
    "id": {
      "from": null,
      "to": "KbwPUnYXaj"
    },
    "created_at": {
      "from": null,
      "to": "2025-07-31T14:21:48.628Z"
    },
    "updated_at": {
      "from": null,
      "to": "2025-07-31T14:21:48.628Z"
    },
    "order_id": {
      "from": null,
      "to": "qRKahzeREv"
    },
    "payment_source_id": {
      "from": null,
      "to": "MPnWZTeybl"
    },
    "payment_source_type": {
      "from": null,
      "to": "CheckoutComPayment"
    }
  },
  "who": {
    "application": {
      "id": "DNOvYirRpn",
      "client_id": "app_cLi3nT-IDFgefXpyTYabocYTOwAGmC3I1Npc",
      "kind": "sales_channel",
      "public": true
    },
    "owner": {
      "id": "QKmohgwbyn",
      "type": "Customer",
      "email": "mark@example.com"
    }
  },
  "uuid": "0725c0a24c721f6625479612415ecb084578ee535cdf46561f1a79a0485aa03c",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
  "ip_address": "83.67.219.209",
  "test": true,
<strong>  "created_at": "2025-07-31T14:21:48.000+00:00"
</strong>}

...

<strong>event: destroy
</strong>id: 1753973120745-0
data: {
  "id": "1753971693969-0",
  "event": "destroy",
  "resource_type": "line_items",
  "resource_id": "kAjVtPobbv",
  "organization_id": "XMlEOFrjdf",
  "payload": {
    "quantity": {
      "from": "1.0",
      "to": null
    },
    "unit_amount_cents": {
      "from": "0.0",
      "to": null
    },
    "compare_at_amount_cents": {
      "from": "0.0",
      "to": null
    },
    "options_amount_cents": {
      "from": "0.0",
      "to": null
    },
    "discount_cents": {
      "from": "0.0",
      "to": null
    },
    "name": {
      "from": "Adyen Payment",
      "to": null
    },
    "item_type": {
      "from": "PaymentMethod",
      "to": null
    },
    "id": {
      "from": "kAjVtPobbv",
      "to": null
    },
    "created_at": {
      "from": "2025-07-31T14:21:10.940Z",
      "to": null
    },
    "updated_at": {
      "from": "2025-07-31T14:21:10.940Z",
      "to": null
    },
    "metadata": {
      "from": {},
      "to": null
    },
    "order_id": {
      "from": "qRKahzeREv",
      "to": null
    },
    "discount_breakdown": {
      "from": {},
      "to": null
    },
    "tax_breakdown": {
      "from": {},
      "to": null
    },
    "rule_outcomes": {
      "from": [],
      "to": null
    }
  },
  "who": {
    "application": {
      "id": "DNOvYirRpn",
      "client_id": "app_cLi3nT-IDFgefXpyTYabocYTOwAGmC3I1Npc",
      "kind": "sales_channel",
      "public": true
    },
    "owner": {
      "id": "QKmohgwbyn",
      "type": "Customer",
      "email": "mark@example.com"
    }
  },
  "uuid": "0725c0a24c721f6625479612415ecb084578ee535cdf46561f1a79a0485aa03c",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
  "ip_address": "83.67.219.209",
  "test": true,
<strong>  "created_at": "2025-07-31T14:21:10.000+00:00"
</strong>}

...

<strong>event: update
</strong>id: 1753973120763-0
data: {
  "id": "1753971672060-0",
  "event": "update",
  "resource_type": "orders",
  "resource_id": "qSKahzeREv",
  "organization_id": "XMlEOFrjdf",
  "payload": {
    "updated_at": {
      "from": "2025-07-31T14:21:10.944Z",
      "to": "2025-07-31T14:21:12.044Z"
    },
    "payment_source_id": {
      "from": null,
      "to": "KZBkghKqkm"
    },
    "payment_source_type": {
      "from": null,
      "to": "AdyenPayment"
    }
  },
  "who": {
    "application": {
      "id": "DNOvYirRpn",
      "client_id": "app_cLi3nT-IDFgefXpyTYabocYTOwAGmC3I1Npc",
      "kind": "sales_channel",
      "public": true
    },
    "owner": {
      "id": "QKmohgwbyn",
      "type": "Customer",
      "email": "mark@example.com"
    }
  },
  "uuid": "0725c0a24c721f6625479612415ecb084578ee535cdf46561f1a79a0485aa03c",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
  "ip_address": "83.67.219.209",
  "test": true,
<strong>  "created_at": "2025-07-31T14:21:12.000+00:00"
</strong>}

...

<strong>event: stream_complete
</strong>data: {
  "event": "stream_complete",
  "message": "Replay stream completed successfully",
  "timestamp": "2025-07-31T14:30:03Z"
}     
</code></pre>

{% endtab %}
{% endtabs %}

#### Replay by resource type

{% tabs %}
{% tab title="Request" %}
The following request replays only the events related to SKUs, streamed within a specified time window:

```sh
curl -g -X GET \
  'https://stream.commercelayer.io/my-org/replay?date_from=2025-07-30T15:15:00Z&date_to=2025-07-31T16:30:00Z&resource_type_eq=skus' \
  -H 'Authorization: Bearer your-access-token' 
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the event stream related to the specified time window and resource type:

<pre><code><strong>event: replay_started
</strong>id: 1753977869951-0
data: {
  "event": "replay_started",
  "timestamp": "2025-07-31T14:30:00Z"
}

<strong>event: create
</strong>id: 1753977870001-0
{
  "id": "1753977666209-0",
  "event": "create",
<strong>  "resource_type": "skus",
</strong>  "resource_id": "BfvMSwEyJW",
  "organization_id": "XMlEOFrjdf",
  "payload": {
    "code": {
      "from": null,
      "to": "NEWCARPETXXX"
    },
    "name": {
      "from": null,
      "to": "New Carpet"
    },
    "description": {
      "from": null,
      "to": "Wonderful carpet: 260x180cm."
    },
    "id": {
      "from": null,
      "to": "BgvMSwEyJW"
    },
    "created_at": {
      "from": null,
      "to": "2025-07-31T16:01:06.160Z"
    },
    "updated_at": {
      "from": null,
      "to": "2025-07-31T16:01:06.160Z"
    },
    "shipping_category_id": {
      "from": null,
      "to": "gKkerFnawZ"
    },
    "pieces_per_pack": {
      "from": null,
      "to": "1.0"
    },
    "weight": {
      "from": null,
      "to": "2000.0"
    },
    "unit_of_weight": {
      "from": null,
      "to": "gr"
    }
  },
  "who": {
    "application": {
      "id": "FMjvdiebqM",
      "client_id": "CappID-cl1ent-26Ugu6zl4kr-KOwFhtKMvQIvj-KZY",
      "kind": "skus",
      "public": false
    },
    "owner": {
      "id": "gEmwmSNRed",
      "type": "User",
      "email": "jack@example.com",
      "first_name": "Jack",
      "last_name": "Doe"
    }
  },
  "uuid": "e8a069b6e5a2619e350357ea5bf32678b91bdca683709fb4e0c9edc737fbcfed",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
  "ip_address": "93.87.228.116",
  "test": true,
<strong>  "created_at": "2025-07-31T16:01:06.000+00:00"
</strong>}

<strong>event: create
</strong>id: 1753977870003-0
data: {
  "id": "1753975304905-0",
  "event": "create",
<strong>  "resource_type": "skus",
</strong>  "resource_id": "nQrOSKprmZ",
  "organization_id": "XMlEOFrjdf",
  "payload": {
    "code": {
      "from": null,
      "to": "NEWCAPXXX"
    },
    "name": {
      "from": null,
      "to": "New Cap"
    },
    "description": {
      "from": null,
      "to": "A brand new cap."
    },
    "id": {
      "from": null,
      "to": "nQrOSKprmZ"
    },
    "created_at": {
      "from": null,
      "to": "2025-07-31T15:21:44.883Z"
    },
    "updated_at": {
      "from": null,
      "to": "2025-07-31T15:21:44.883Z"
    },
    "shipping_category_id": {
      "from": null,
      "to": "VNoxGFBywb"
    },
    "pieces_per_pack": {
      "from": null,
      "to": "1.0"
    },
    "weight": {
      "from": null,
      "to": "100.0"
    },
    "unit_of_weight": {
      "from": null,
      "to": "gr"
    }
  },
  "who": {
    "application": {
      "id": "FMjvdiebqM",
      "client_id": "CappID-cl1ent-26Ugu6zl4kr-KOwFhtKMvQIvj-KZY",
      "kind": "skus",
      "public": false
    },
    "owner": {
      "id": "gEmwmSNRed",
      "type": "User",
      "email": "jack@example.com",
      "first_name": "Jack",
      "last_name": "Doe"
    }
  },
  "uuid": "e8a069b6e5a2619e350357ea5bf32678b91bdca683709fb4e0c9edc737fbcfed",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
  "ip_address": "93.87.228.116",
  "test": true,
<strong>  "created_at": "2025-07-31T15:21:44.000+00:00"
</strong>}

<strong>event: update
</strong>id: 1753977869996-0
data: {
  "id": "1753975080985-0",
  "event": "update",
<strong>  "resource_type": "skus",
</strong>  "resource_id": "WJoqSjzGjB",
  "organization_id": "XMlEOFrjdf",
  "payload": {
    "name": {
      "from": "Batman Coffee Mug",
      "to": "Batman Mug"
    },
    "description": {
      "from": "Batman branded mug. Ideal for coffee.",
      "to": "Batman branded mug."
    },
    "updated_at": {
      "from": "2025-07-31T13:58:58.798Z",
      "to": "2025-07-31T15:18:00.950Z"
    },
    "weight": {
      "from": "400.0",
      "to": "300.0"
    }
  },
  "who": {
    "application": {
      "id": "DMjvdiebqM",
      "client_id": "app-ID-Cl1ent-oIc326Ugu6zl4kr-KOwFhtKMvQIvj-KZY",
      "kind": "skus",
      "public": false
    },
    "owner": {
      "id": "pthwmSNSed",
      "type": "User",
      "email": "jane@example.com",
      "first_name": "Jane",
      "last_name": "Doe"
    }
  },
  "uuid": "31acbaf6f6c36552b0bab4dd683b02e9ab3a028bd14330f9b9dc0d1190763aab",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
  "ip_address": "93.43.228.116",
  "test": true,
<strong>  "created_at": "2025-07-31T15:18:00.000+00:00"
</strong>}

<strong>event: update
</strong>id: 1753977869997-0
data: {
  "id": "1753975114234-0",
  "event": "update",
<strong>  "resource_type": "skus",
</strong>  "resource_id": "WJoqSjzGjB",
  "organization_id": "XMlEOFrjdf",
  "payload": {
    "description": {
      "from": "Batman branded mug.",
      "to": "Batman branded mug. Top seller!"
    },
    "updated_at": {
      "from": "2025-07-31T15:18:00.950Z",
      "to": "2025-07-31T15:18:34.201Z"
    }
  },
  "who": {
    "application": {
      "id": "DMjvdiebqM",
      "client_id": "app-ID-Cl1ent-oIc326Ugu6zl4kr-KOwFhtKMvQIvj-KZY",
      "kind": "skus",
      "public": false
    },
    "owner": {
      "id": "pthwmSNSed",
      "type": "User",
      "email": "jane@example.com",
      "first_name": "Jane",
      "last_name": "Doe"
    }
  },
  "uuid": "31acbaf6f6c36552b0bab4dd683b02e9ab3a028bd14330f9b9dc0d1190763aab",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
  "ip_address": "93.43.228.116",
  "test": true,
<strong>  "created_at": "2025-07-31T15:18:34.000+00:00"
</strong>}

<strong>event: destroy
</strong>id: 1753977869999-0
data: {
  "id": "1753977604269-0",
  "event": "destroy",
<strong>  "resource_type": "skus",
</strong>  "resource_id": "nQrOSKprmZ",
  "organization_id": "XMlEOFrjdf",
  "payload": {
    "code": {
      "from": "NEWCAPXXX",
      "to": null
    },
    "name": {
      "from": "New Cap",
      "to": null
    },
    "description": {
      "from": "A brand new cap.",
      "to": null
    },
    "do_not_ship": {
      "from": false,
      "to": null
    },
      "do_not_track": {
      "from": false,
      "to": null
    },
    "id": {
      "from": "nQrOSKprmZ",
      "to": null
    },
    "created_at": {
      "from": "2025-07-31T15:21:44.883Z",
      "to": null
    },
    "updated_at": {
      "from": "2025-07-31T15:21:44.883Z",
      "to": null
    },
    "metadata": {
      "from": {},
      "to": null
    },
    "shipping_category_id": {
      "from": "VNoxGFBywb",
      "to": null
    },
    "pieces_per_pack": {
      "from": "1.0",
      "to": null
    },
    "weight": {
      "from": "100.0",
      "to": null
    },
    "unit_of_weight": {
      "from": "gr",
      "to": null
    }
  },
  "who": {
    "application": {
      "id": "FMjvdiebqM",
      "client_id": "CappID-cl1ent-26Ugu6zl4kr-KOwFhtKMvQIvj-KZY",
      "kind": "skus",
      "public": false
    },
    "owner": {
      "id": "gEmwmSNRed",
      "type": "User",
      "email": "jack@example.com",
      "first_name": "Jack",
      "last_name": "Doe"
    }
  },
  "uuid": "e8a069b6e5a2619e350357ea5bf32678b91bdca683709fb4e0c9edc737fbcfed",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
  "ip_address": "93.87.228.116",
  "test": true,
<strong>  "created_at": "2025-07-31T15:15:44.000+00:00"
</strong>}

...

<strong>event: stream_complete
</strong>data: {
  "event": "stream_complete",
  "message": "Replay stream completed successfully",
  "timestamp": "2025-07-31T14:30:03Z"
}     
</code></pre>

{% endtab %}
{% endtabs %}

#### Replay by resource IDs

{% tabs %}
{% tab title="Request" %}
The following request replays only the events related to the SKUs identified by the IDs `nQrOSKprmZ` and `WJoqSjzGjB` with no time window restriction:

```sh
curl -g -X GET \
  'https://stream.commercelayer.io/my-org/replay?resource_type_eq=skus&resource_id_in=nQrOSKprmZ,WJoqSjzGjB' \
  -H 'Authorization: Bearer your-access-token' 
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the event stream related to the specified resource type and IDs:

<pre><code><strong>event: replay_started
</strong>id: 1753977869951-0
data: {
  "event": "replay_started",
  "timestamp": "2025-07-31T14:30:00Z"
}

<strong>event: create
</strong>id: 1753977870003-0
data: {
  "id": "1753975304905-0",
  "event": "create",
<strong>  "resource_type": "skus",
</strong><strong>  "resource_id": "nQrOSKprmZ",
</strong>  "organization_id": "XMlEOFrjdf",
  "payload": {
    "code": {
      "from": null,
      "to": "NEWCAPXXX"
    },
    "name": {
      "from": null,
      "to": "New Cap"
    },
    "description": {
      "from": null,
      "to": "A brand new cap."
    },
    "id": {
      "from": null,
      "to": "nQrOSKprmZ"
    },
    "created_at": {
      "from": null,
      "to": "2025-07-31T15:21:44.883Z"
    },
    "updated_at": {
      "from": null,
      "to": "2025-07-31T15:21:44.883Z"
    },
    "shipping_category_id": {
      "from": null,
      "to": "VNoxGFBywb"
    },
    "pieces_per_pack": {
      "from": null,
      "to": "1.0"
    },
    "weight": {
      "from": null,
      "to": "100.0"
    },
    "unit_of_weight": {
      "from": null,
      "to": "gr"
    }
  },
  "who": {
    "application": {
      "id": "FMjvdiebqM",
      "client_id": "CappID-cl1ent-26Ugu6zl4kr-KOwFhtKMvQIvj-KZY",
      "kind": "skus",
      "public": false
    },
    "owner": {
      "id": "gEmwmSNRed",
      "type": "User",
      "email": "jack@example.com",
      "first_name": "Jack",
      "last_name": "Doe"
    }
  },
  "uuid": "e8a069b6e5a2619e350357ea5bf32678b91bdca683709fb4e0c9edc737fbcfed",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
  "ip_address": "93.87.228.116",
  "test": true,
  "created_at": "2025-07-31T15:21:44.000+00:00"
}

<strong>event: update
</strong>id: 1753977869996-0
data: {
  "id": "1753975080985-0",
  "event": "update",
<strong>  "resource_type": "skus",
</strong><strong>  "resource_id": "WJoqSjzGjB",
</strong>  "organization_id": "XMlEOFrjdf",
  "payload": {
    "name": {
      "from": "Batman Coffee Mug",
      "to": "Batman Mug"
    },
    "description": {
      "from": "Batman branded mug. Ideal for coffee.",
      "to": "Batman branded mug."
    },
    "updated_at": {
      "from": "2025-07-31T13:58:58.798Z",
      "to": "2025-07-31T15:18:00.950Z"
    },
    "weight": {
      "from": "400.0",
      "to": "300.0"
    }
  },
  "who": {
    "application": {
      "id": "DMjvdiebqM",
      "client_id": "app-ID-Cl1ent-oIc326Ugu6zl4kr-KOwFhtKMvQIvj-KZY",
      "kind": "skus",
      "public": false
    },
    "owner": {
      "id": "pthwmSNSed",
      "type": "User",
      "email": "jane@example.com",
      "first_name": "Jane",
      "last_name": "Doe"
    }
  },
  "uuid": "31acbaf6f6c36552b0bab4dd683b02e9ab3a028bd14330f9b9dc0d1190763aab",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
  "ip_address": "93.43.228.116",
  "test": true,
  "created_at": "2025-07-31T15:18:00.000+00:00"
}

<strong>event: update
</strong>id: 1753977869997-0
data: {
  "id": "1753975114234-0",
  "event": "update",
<strong>  "resource_type": "skus",
</strong><strong>  "resource_id": "WJoqSjzGjB",
</strong>  "organization_id": "XMlEOFrjdf",
  "payload": {
    "description": {
      "from": "Batman branded mug.",
      "to": "Batman branded mug. Top seller!"
    },
    "updated_at": {
      "from": "2025-07-31T15:18:00.950Z",
      "to": "2025-07-31T15:18:34.201Z"
    }
  },
  "who": {
    "application": {
      "id": "DMjvdiebqM",
      "client_id": "app-ID-Cl1ent-oIc326Ugu6zl4kr-KOwFhtKMvQIvj-KZY",
      "kind": "skus",
      "public": false
    },
    "owner": {
      "id": "pthwmSNSed",
      "type": "User",
      "email": "jane@example.com",
      "first_name": "Jane",
      "last_name": "Doe"
    }
  },
  "uuid": "31acbaf6f6c36552b0bab4dd683b02e9ab3a028bd14330f9b9dc0d1190763aab",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
  "ip_address": "93.43.228.116",
  "test": true,
  "created_at": "2025-07-31T15:18:34.000+00:00"
}

<strong>event: destroy
</strong>id: 1753977869999-0
data: {
  "id": "1753977604269-0",
  "event": "destroy",
<strong>  "resource_type": "skus",
</strong><strong>  "resource_id": "nQrOSKprmZ",
</strong>  "organization_id": "XMlEOFrjdf",
  "payload": {
    "code": {
      "from": "NEWCAPXXX",
      "to": null
    },
    "name": {
      "from": "New Cap",
      "to": null
    },
    "description": {
      "from": "A brand new cap.",
      "to": null
    },
    "do_not_ship": {
      "from": false,
      "to": null
    },
      "do_not_track": {
      "from": false,
      "to": null
    },
    "id": {
      "from": "nQrOSKprmZ",
      "to": null
    },
    "created_at": {
      "from": "2025-07-31T15:21:44.883Z",
      "to": null
    },
    "updated_at": {
      "from": "2025-07-31T15:21:44.883Z",
      "to": null
    },
    "metadata": {
      "from": {},
      "to": null
    },
    "shipping_category_id": {
      "from": "VNoxGFBywb",
      "to": null
    },
    "pieces_per_pack": {
      "from": "1.0",
      "to": null
    },
    "weight": {
      "from": "100.0",
      "to": null
    },
    "unit_of_weight": {
      "from": "gr",
      "to": null
    }
  },
  "who": {
    "application": {
      "id": "FMjvdiebqM",
      "client_id": "CappID-cl1ent-26Ugu6zl4kr-KOwFhtKMvQIvj-KZY",
      "kind": "skus",
      "public": false
    },
    "owner": {
      "id": "gEmwmSNRed",
      "type": "User",
      "email": "jack@example.com",
      "first_name": "Jack",
      "last_name": "Doe"
    }
  },
  "uuid": "e8a069b6e5a2619e350357ea5bf32678b91bdca683709fb4e0c9edc737fbcfed",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
  "ip_address": "93.87.228.116",
  "test": true,
  "created_at": "2025-07-31T15:15:44.000+00:00"
}

...

<strong>event: stream_complete
</strong>data: {
  "event": "stream_complete",
  "message": "Replay stream completed successfully",
  "timestamp": "2025-07-31T14:30:03Z"
}     
</code></pre>

{% endtab %}
{% endtabs %}

## Response codes

The Commerce Layer Stream Hub uses [HTTP response codes](https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) to show the success or failure of a [request to connect](#connecting-to-the-event-stream) to the event stream.

### Success

In case of successful connection, the API responds with a `200 OK` status code and starts streaming data according to the SSE format.

### Error

In case of error, a descriptive error message is returned along with the related error code:

<table><thead><tr><th width="87.01171875">Code</th><th width="218.60546875"></th><th>Description</th></tr></thead><tbody><tr><td><strong><code>400</code></strong></td><td><code>Bad request</code></td><td>The date format is invalid or the date range validation failed.</td></tr><tr><td><strong><code>401</code></strong></td><td><code>Unauthorized</code></td><td>The JWT token is invalid (expired, not associated with integration API credentials, etc.) or missing.</td></tr><tr><td><strong><code>403</code></strong></td><td><code>Forbidden</code></td><td>An organization slug mismatch or validation error occurred.</td></tr><tr><td><strong><code>409</code></strong></td><td><code>Conflict</code></td><td>An active consumer already exists (you can kill the stream and retry in 5 secs).</td></tr><tr><td><strong><code>500</code></strong></td><td><code>Internal server error</code></td><td>Something went wrong and the stream hub failed to queue the replay job.</td></tr></tbody></table>

## How to enable the stream hub

Enterprise customers who want to leverage the power of our event stream hub must activate it at the organization level by environment. This can be done:

* [Directly from the Dashboard](#stream-settings)
* [Using the Provisioning API](#organization-config)

### Stream settings

To enable the event stream hub from the Dashboard UI, click on the *Settings* menu item of the left sidebar and access the *General > Organization* section:

<figure><img src="/files/ArMZWmwtE7rb8o6BmHgP" alt=""><figcaption></figcaption></figure>

Then select the stream scope from the dropdown menu and click *Update*:

<figure><img src="/files/Zw1aCaYIiDWlukEwSxo1" alt=""><figcaption></figcaption></figure>

### Organization config

To enable the event stream hub via API, patch the [organizations](/provisioning/api-reference/organizations) endpoint and pass the `api.stream` object within the `config` attribute, setting the stream `scope` (can be one of `none`, `live`, `test`, or `both`):

<pre class="language-json" data-title="organizations.config"><code class="lang-json">{
  "api": {
    "stream": {
<strong>      "scope": "live"
</strong>    }
  }
}
</code></pre>


# Callbacks security

How to verify callbacks authenticity

For security reasons, when sending and receiving data and information to and from an external endpoint (i.e. [real-time webhooks](/core/real-time-webhooks), [external resources](/core/external-resources)) we recommend verifying the callback authenticity by signing the payload with the shared secret ([SHA256 HMAC](https://en.wikipedia.org/wiki/HMAC)) and comparing the result with the **X-CommerceLayer-Signature** callback header. In details:

1. Read the **X-CommerceLayer-Signature** header and get the encrypted signature.
2. Rebuild the signature according to the SHA256 HMAC algorithm, using the payload body and the provided shared secret.
3. Compare your signature with the one you got from the header.
4. If the two signatures match, you can proceed safely — if not, you can't trust the callback.

#### Example

This is a sample script in **Node.js** that you can use as a reference to check the signature:

```javascript
import { createHmac } from "node:crypto";

export default (req, res) => {
  const signature = req.headers['x-commercelayer-signature']
  
  const encode = createHmac("sha256", process.env.CL_SHARED_SECRET)
    .update(req.body)
    .digest("base64");
  
  if (req.method === 'POST' && signature === encode) {
		// your-code
    res.status(200).json({
      success: true,
    })
  } else {
    res.status(401).json({
      error: 'Unauthorized',
    })
  }
}
```

{% hint style="warning" %}
When verifying the callback authenticity, make sure to read the **raw body** of the payload and NOT the parsed one.
{% endhint %}

{% hint style="info" %}
Do you prefer to use [Next.js](https://github.com/commercelayer/examples/tree/main/webhooks/nextjs-signature-verification) or [Express.js](https://github.com/commercelayer/examples/tree/main/webhooks/expressjs-signature-verification) to verify the signature? Check the linked code samples from our [Examples](https://github.com/commercelayer/examples/) open-source repository on GitHub.
{% endhint %}

## IP ranges

All the external requests (i.e. [real-time webhooks](/core/real-time-webhooks), [external resources](/core/external-resources)) are sent from a set of dedicated IP addresses. When you receive requests to your endpoints, please make sure their source IP is included in the following lists:

| Region          | IPs                                                                                          | Description                                                                |
| --------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| **`eu-west-1`** | <p><code>54.246.59.198</code><br><code>99.81.212.137</code><br><code>54.74.119.33</code></p> | Source IPs for customers with organization localized in the **EU region**. |
| **`us-east-1`** | <p><code>3.220.172.67</code><br><code>34.202.177.238</code><br><code>52.0.55.171</code></p>  | Source IPs for customers with organization localized in the **US region**. |

{% hint style="info" %}
In case there are any changes to the list of IPs above, they will be communicated widely in advance through all our channels.
{% endhint %}


# Overview

A map of Commerce Layer's resources and how they work together

A **data model** is the backbone of any API-driven platform. It defines the resources that power your application and the relationships connecting them. Think of it as a blueprint showing how different entities interact and depend on each other to deliver functionality.

**Commerce Layer**'s data model represents years of refining how commerce should work in a headless, composable architecture. It shows how products, inventory, orders, customers, and payments work together, handling the complexity of modern multi-channel retail while remaining flexible to your unique business needs.

## Why a data model matters

Understanding resource relationships is essential for building effectively. When you know that a market connects price lists, inventory models, and shipping methods, you can quickly configure multi-country operations. When you understand how SKUs, bundles, and stock items interact, you can design sophisticated product catalogs with confidence.

The data model helps you plan integrations, optimize API calls, and troubleshoot issues. Instead of discovering relationships through trial and error, you see the complete picture upfront and make informed architectural decisions.

## Why we make it public

Transparency is core to how we operate. Developers should have complete visibility into the system they're building on. By documenting our data model, we enable you to design your commerce architecture with full knowledge of capabilities and constraints, understand the impact of decisions before writing code, build integrations that work with the platform's design, and evaluate whether Commerce Layer fits your use case.

This documentation includes [E-R diagrams](https://en.wikipedia.org/wiki/Entity%E2%80%93relationship_model) for major resource groups, showing relationships, key attributes, and data flow. Whether you're architecting a new solution or extending an existing one, this guide helps you understand not just what Commerce Layer does, but how.

Each page focuses on a specific domain. Start with areas most relevant to your immediate needs, but don't forget to explore related domains — commerce operations are interconnected, and powerful implementations leverage relationships across multiple resource groups.

## Reading the diagrams

The entity-relationship diagrams use standard notation to show how resources connect. Each line between resources represents a relationship, with symbols indicating cardinality:

* **1** — exactly one (required)
* **N** — many
* **0** — optional (can be zero)

Common patterns include **1 — N** (one-to-many), **1 — 1** (one-to-one), **0-1** (zero-or-one), and **N — N** (many-to-many). For example, a market has many price lists (1 — N), while a price list can be optionally associated with one or more price list schedulers (0-1 — N).

The resource(s) each page focuses on and the connections to their direct relationships are highlighted with an accent color:

<figure><img src="/files/x9DVFqoLuHIw1DeLUI36" alt=""><figcaption></figcaption></figure>


# Users and organizations

From account creation to team structure, access control, and API credential management

<figure><img src="/files/OJtgjkgOelyYHMfhZS56" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
A user account gives access to Commerce Layer. Each user can belong to one or more independent organizations. Within each org, you invite members, assign roles and permissions, and configure the API applications your team needs.
{% endhint %}

## Users

[Users](/provisioning/api-reference/user) are individuals who create an account in Commerce Layer. A user can create or join one or more organizations. Within each organization, they can manage memberships and assign or receive specific roles and permissions. To become a user, you need to [sign up](https://dashboard.commercelayer.io/sign_up) using an email address or one of the other available options.

## Organizations

An [organization](/provisioning/api-reference/organizations) is an independent group that comprises members with assigned roles and permissions. A user can manage many companies, clients, or merchants within a single account by using one or more organizations. With the appropriate permissions, members can create new merchants, markets, and business models for each market without any data duplication.

## Members, roles, and permissions

Each organization is completely independent. You can invite one or more users to join an organization and assign them a [role](/provisioning/api-reference/roles) — either *Admin* or *Member*. New members receive an invitation by email and will be prompted to create an account if they don't already have one.

[Enterprise](https://commercelayer.io/pricing) users can define custom roles and assign [permissions](/provisioning/api-reference/permissions) to each role, allowing different members to have different privileges across the organization.

## Applications

Each organization has its own set of [applications](/core-api-reference/application), which define the [API credentials](/provisioning/api-reference/api_credentials) your team uses to build on Commerce Layer. Three types of applications are available, each with a role that grants different permissions:

* **Sales channel** — *non-confidential* (public) API credentials for building any customer-facing touchpoint. Their permissions are restricted so that they can be safely used client-side without exposing sensitive data.
* **Integration** — *confidential* API credentials for backend integrations with third-party systems. They can have one of two roles: *Read-only* or *Admin*.
* **Webapp** — used to build custom web apps or services that extend Commerce Layer with functionality not available out of the box. They don't have predefined roles and permissions: they inherit the permissions of the authenticated user.


# Merchants and customers

Market ownership, customer segmentation by purchase history, and group-based access control

<figure><img src="/files/XtKsxEouJp4tEnBcArHc" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
Each market belongs to one merchant, who defines its business model and price list. Customers are categorized by purchase history. Customer groups give selected customers private access to markets, promotions, and more.
{% endhint %}

## Merchants

A [merchant](/core-api-reference/merchants) is the seller or owner of each market in an organization. You can associate the same merchant with one or more markets.

An organization may have one or more merchants, each with its own billing address. The merchant defines the market's business model, inventory model, and price list for customers in that market.

## Customers

[Customers](/core-api-reference/customers) are individuals who make purchases from an ecommerce sales channel. They are identified by their email addresses.

There are three categories of customers in Commerce Layer:

* **Prospect customers** — customers who have not placed an order yet.
* **Acquired customers** — customers who have placed only one order.
* **Repeat customers** — customers who have placed more than one order.

Commerce Layer's [order management system](https://commercelayer.io/distributed-oms) lets you manage customers in an organization. You can also export customers to any external CRM (customer relationship management) or marketing tool to manage campaigns, loyalty programs, and more.

## Customer groups

[Customer groups](/core-api-reference/customer_groups) are a collection of selected customers. You can organize and associate a customer group with a market. All customers in a particular group get private access to a market, promotions, campaigns, loyalty programs, and more.

You can also use customer groups to manage B2B, B2C, subscription, private sales, and marketplace business models.


# SKUs

Connecting your CMS to transactional commerce, digital and infinite-stock products included

<figure><img src="/files/6sxeBoGOre2YkwAycTc3" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
SKUs are the link between your product catalog and Commerce Layer. Each SKU can have prices across multiple price lists and stock items across many locations. Two flags let you handle digital and infinite-stock products.
{% endhint %}

## What is a SKU?

SKU stands for *Stock Keeping Unit*. It is a unique identifier for a specific product variant, used to track availability and stock variations of an item (e.g., the *Medium* or *Large* size of a jogger pant).

{% hint style="info" icon="circle-info" %}

#### Commerce Layer is not a content management system

Commerce Layer handles the transactional side of commerce, leaving all product, category, and catalog information to the CMS of your choice. The SKU code is the link between the two — tied to a single variant, not to a generic "product".
{% endhint %}

A [SKU](/core-api-reference/skus) consists of letters and numbers (EAN code, UPC, or any other format), such as `LSLEEVMM000000FFFFFFMXXX`. It identifies each variant's characteristics: manufacturer name, brand, style, color, weight, size, and more.

Each SKU can have one or more prices in one or more price lists, and many stock items across many stock locations. The presence of both a price and a stock item determines the SKU's availability for a given market or customer group.

## Digital products

SKUs usually refer to physical goods ready to be shipped to the customer. That's the most common case, but not the only one.

Commerce Layer offers two flags for handling other scenarios:

* **Do not ship** — prevents shipment creation when the SKU is added to an order. The relationship with a shipping category is optional in this case.
* **Do not track** — makes the SKU always available regardless of stock levels.

Combining these two flags lets you handle scenarios such as intangible products that generate no shipment and products with a virtually infinite stock.


# SKU options

Custom personalization services and add-ons that can be attached to SKUs within a market

<figure><img src="/files/Z9eGYwSZiQlqAspMqoFp" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
SKU options are market-defined add-ons that customers can attach to SKUs during an order. They can affect price or delivery lead time, and their cost is automatically added to the line item's amount.
{% endhint %}

## What is a SKU option?

[SKU options](/core-api-reference/sku_options) represent any custom personalization or additional service defined by a market. Customers can add these options to selected SKUs during an order. The additional service can affect the price or delivery lead time of an SKU due to an update in preparation time. Any additional cost is automatically added to the line item's amount, and the order is refreshed with updated data once the option is applied.

SKU options can be predefined per market with the related SKU codes, delay time, or price. Typical examples include engraving, customized prints, and customized wrapping. To add one or more SKU options to a line item, you need to create a line item option.


# SKU lists

Grouping SKUs for filtering, promotions, bundles, and other use cases

<figure><img src="/files/ztvRD9oPugDCTxZIfw3Z" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
SKU lists group multiple SKUs into a collection. Items can be added manually or via a regular expression. Use them for promotions, filtering, and building bundles with a special market price.
{% endhint %}

## What is a SKU list?

[SKU lists](/core-api-reference/sku_lists) are used to group many SKUs into a collection that can be filtered and exposed to customers in the presentation layer. You can create a SKU list by selecting and sorting items from the available SKUs manually, or by using a regular expression to populate and sort them automatically.

SKU lists let you:

* Filter, display, or apply rules to a selected set of SKUs, including their prices and availability.
* Enable and manage promotions for a set of SKUs.
* Restrict the scope of a promotion to a set of SKUs.
* Group SKUs into a bundle assigned to a market with a special price.


# Bundles

Grouping multiple SKUs with a special price for a market

<figure><img src="/files/Guucf7Zz0SBKZRPuD8t3" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
A bundle groups multiple SKUs into a collection with a special price, activated within a market. Only a manual SKU list can be linked to a bundle, and it cannot be modified once associated.
{% endhint %}

## What is a bundle?

A [bundle](/core-api-reference/bundles) is a collection of SKUs sold together at a special price. The SKUs are associated with the bundle via SKU list items belonging to a manual SKU list — only manual SKU lists can be linked to a bundle.

Bundles can be activated within a specific market. Once a price is assigned, the currency is inherited from the market relationship. If no market is specified, a currency must be assigned directly to the bundle. You can set both a price amount and a compared price amount, which is often used to display a percentage discount. The compared price can also be calculated automatically as the sum of all individual SKU prices in the bundle.

A maximum of ten SKU list items is allowed for the SKU list assigned to a bundle. Once a SKU list is associated with a bundle, it cannot be modified — new items cannot be added, deleted, or updated unless the linked bundle is first deleted.

## Creating a bundle

Creating a bundle for a market requires three steps:

1. Create some SKUs.
2. Create a manual SKU list and assign SKUs to it via SKU list items.
3. Create a bundle with an associated SKU list, special price, and market.

Once set up, you can use the bundle in a sales channel as needed.

## Use cases

Bundles are a good fit for:

* Selling **special kits** that include multiple items.
* Selling **gift sets** that include items with multiple variants.
* Selling **gift boxes** that include multiple items.
* Selling products that are only available as part of a bundle and cannot be purchased individually.


# Stock locations

Holding SKU inventory per location, acting as building blocks for inventory models, and enabling fulfillment and returns

<figure><img src="/files/ESbgBWRV7dvH768nk65a" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
Stock locations hold the stock items that make up an organization's inventory and are the building blocks of inventory models. Inventory stock locations drive SKU availability, return stock locations define return options.
{% endhint %}

## What is a stock location?

[Stock locations](/core-api-reference/stock_locations) hold stock items — the available inventory of an SKU — that are to be sold. They are the building blocks of inventory models. An organization may have one or more stock locations, each with its own unique address.

You can manage SKUs' inventory in a stock location, including raw materials, processed goods, and finished products. This lets merchants track which SKUs are available for sale and manage their availability across one or more locations.

Two types of stock locations play distinct roles in Commerce Layer:

* **Inventory stock locations** — determine the availability of SKUs being purchased.
* **Return stock locations** — determine the available options for returns.


# Inventory models

Structuring stock locations by priority and choosing a fulfillment strategy for each market

<figure><img src="/files/3Z1G0vUz3Iotj6cFphsw" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
An inventory model groups stock locations in a priority order that determines SKU availability. The chosen strategy controls how many shipments are generated and from which locations they are fulfilled.
{% endhint %}

## What is an inventory model?

An [inventory model](/core-api-reference/inventory_models) comprises several stock locations ordered by priority. The priority order determines how SKU availability gets calculated within a market.

Two types of stock locations make up an inventory model:

* **Inventory stock locations** — build a hierarchy of stock locations used for fulfillment. They can be a physical warehouse, a retail store, or a virtual location. When an SKU is available in multiple locations, it is shipped from the one with the highest priority.
* **Return stock locations** — build a hierarchy of stock locations used for returns. When an SKU is available in multiple locations, it is returned to the one with the highest priority.

When a customer purchases an item, the available inventory stock locations are checked against the required SKU and quantity to determine availability. You can also retrieve availability information for each SKU in every market, including shipping costs and delivery lead times for each delivery option.

## Inventory strategies

The [inventory model strategy](/how-tos/inventory/strategies) controls how many shipments are generated and from which stock location each shipment will be fulfilled:

* **No split** — only the primary stock location is checked and one shipment is created to fulfill all line items (default strategy).
* **Split shipments** — the order is split into as many shipments as needed based on availability across stock locations.
* **Split by line items** — at least one separate shipment is created per line item.
* **Ship from primary** — all items ship from the primary stock location. If it cannot fulfill all of them, the necessary stock transfers from secondary locations to the primary are performed.
* **Ship from first available (or primary)** — items ship from the first stock location that can fulfill them all. If no such location exists, stock transfers from secondary locations to the primary are performed as a fallback. This strategy minimizes both the number of shipments and stock transfers.


# Stock items

Tracking SKU inventory per location, with stock reservations managing availability throughout the order lifecycle

<figure><img src="/files/kiqzb4dtgMHkp20zcSoN" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
A stock item represents the inventory of an SKU in a given stock location. Stock is automatically reserved when an order is placed and decremented on approval. Manual early reservation is also supported.
{% endhint %}

## What is a stock item?

A [stock item](/core-api-reference/stock_items) is the inventory of an SKU in a given stock location.

{% hint style="warning" %}
The actual *available* quantity may differ from the total stock, as it accounts for any active [stock reservations](#how-stock-reservation-works).
{% endhint %}

When an order is approved, stock item quantities are decremented. When a return is approved and items are restocked, they are incremented.

When creating a stock item, the associated SKU must be available in one of the market's stock locations. The quantity you set represents the initial stock level for that SKU in that location.

## How stock reservation works

Unless triggered manually, stock is automatically reserved when an order is placed. This creates stock reservations in *pending* status for each line item. At this stage, quantities are not yet decremented — the actual availability equals the stock item quantity minus the reserved quantity.

Once the order is approved, quantities are decremented and the stock reservations are deleted. If the order is cancelled, the reserved stock is released and the reservations are also deleted.

Stock associated with an SKU or bundle line item can also be reserved before the order is placed, using a trigger attribute via an integration application (limited to integrations for security reasons). In this case, stock reservations are created in *draft* status and moved to *pending* when the order is placed. Manually triggered reservations expire after **1 hour** by default — this can be changed at the inventory model level. If the order is not placed before expiration, or the line item is removed, the reserved stock is released.

{% hint style="info" %}
Stock reservations act on the whole line item quantity. If the available stock is split across multiple stock locations, multiple stock reservations are created.
{% endhint %}


# Price lists and currencies

SKU pricing per market, schedulers, tiered pricing, and external price calculation

<figure><img src="/files/aNtEgno1j2VLE3TOTBXd" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
Price lists are collections of SKU prices defined by currency and market. Only SKUs with a price in the active price list and stock in a market location are sellable. Schedulers, price tiers, and external pricing add further flexibility.
{% endhint %}

## Price lists

[Price lists](/core-api-reference/price_lists) are collections of SKU prices, defined by currency and market. When fetching SKUs, only those with a price in the market's active price list and at least one stock item in one of the market's stock locations are returned. You can create price lists to manage international business or B2B/B2C pricing models.

### Price list schedulers

A [price list scheduler](https://docs.commercelayer.io/core-api-reference/) associates an alternative price list with a market, overriding the market's default price list for a defined time frame. The scheduler and the market must share the same currency and tax policy. If multiple schedulers are active at the same time, the one that started first takes priority. If multiple schedulers start at the same time, the one that ends first applies.

## Prices and currencies

A [price](/core-api-reference/prices) is the cost of an SKU associated with a currency and a price list. When a customer purchases an SKU, the price is taken from the order's active price list for that market. The same SKU can have a different price in each market — for example, $50 in *List A* for the US market and €45 in *List B* for the EUR market.&#x20;

{% hint style="warning" %}
SKUs without a price in the active price list are not *sellable* in that market.
{% endhint %}

### Price tiers

Commerce Layer supports up to **10 price tiers** per price. Two types of [tiers](/core-api-reference/price_tiers) are available:

* **Volume-based tiers** — the price of an SKU is determined by the tier the total quantity purchased falls within.
* **Frequency-based tiers** — the price of an SKU is determined by the tier the purchase frequency falls within. Typically used to apply discounts for recurring purchases.

### External prices

For more dynamic pricing or custom calculation logic, you can manage SKU prices [using an external service](/core/external-resources/external-prices). Set the external API endpoint at the market level and it will calculate the unit price of each SKU upon request.


# Markets and business models

Market structure, configuration options, and supported business models including B2C, B2B, and private sales

<figure><img src="/files/cYlmP2KPRSKwBruA27r9" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
A market defines a geographical selling region, combining a merchant, price list, and inventory model. Commerce Layer supports multiple business models — B2C, B2B, private sales, and more — each configurable through market settings.
{% endhint %}

## Markets

A [market](/core-api-reference/markets) is a location in a geographical region where merchants sell and customers purchase. An organization may have one or more markets, each associated with SKUs, prices, stock items, and more. Every market requires a merchant, an inventory model, and a price list. You can also associate it with a customer group and, optionally, a geocoder, a tax calculator, one or more price list schedulers, and one or more stores.

The merchant is the legal entity of the market. The price list defines the prices that apply to SKUs in that market and their currency. For specific time windows — such as seasonal sales — the market's price list can be overridden by a different one associated with a price list scheduler. The inventory model determines how inventory is provided in the market.

When obtaining an access token, a market scope filters the market's resources. If a store is in scope, the associated market is inherited from it. Customer groups allow selected customers private access to a market, promotions, and more.

Markets can be enabled or disabled — useful for temporarily activating private sales, testing new market setups, and more.&#x20;

{% hint style="warning" %}
Your [pricing plan](https://commercelayer.io/pricing) limits refer to *active* (enabled) markets only. If you've reached your plan's limit, disable an active market before enabling a new one.
{% endhint %}

At the market level, you can also set a default payment method and shipping method, automatically applied to any order or shipment in the market not already associated with one.

## Business models

Commerce Layer supports several business models, each affecting the configuration of payment methods, shipping methods, price lists, and more.

### Business to customers (B2C)

B2C is a transaction between a business and an end-user, covering everything from the sales channel to how a customer purchases a product.

B2C can be used for single markets, global ecommerce, VIP sales, and more. Customers don't need to be registered to browse or check out.

### Business to business (B2B)

B2B is a transaction between businesses — typically a manufacturer and a wholesaler, or a wholesaler and a retailer who then resells to end-users.

Only logged-in and verified customers can make purchases in a B2B model. Customer groups manage access by granting private entry to a market, promotions, campaigns, and more.

There are two common ways to set up a B2B model:

* Assign a specific price list to the market associated with the B2B customer group. All business rules and promotions apply to that price list.
* Assign the public price list to the market and create a promotion (e.g., a percentage discount) for that market. Business rules and promotions apply to both the price list and the promotion rules.

### VIP or private sales

A private sale is a transaction between a business and a specific group of customers. A VIP market is set up with associated price lists, promotions, and loyalty programs. Only customers belonging to the VIP customer group have access.


# Stores

Mapping physical sales points to markets, with store-specific stock, payment methods, and in-store shipment handling

<figure><img src="/files/5PIkHBXfvWlBZxv896pw" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
A store belongs to a market and maps a physical sales point. Stores can have their own stock location, payment methods, and merchant. When a store is in scope, resources are filtered and orders are associated with that store.
{% endhint %}

## What is a store?

A [store](/core-api-reference/stores) belongs to a specific market and maps the market's physical sales points — retail stores, pop-up stores, and similar — for managing in-store sales.

Stores can optionally have a different merchant (otherwise inherited from the associated market), a store-specific stock location, and one or more store-specific payment methods.

When a store is put in scope during an access token request, all fetched resources (SKUs, prices, etc.) are automatically filtered by the associated market, orders are linked to the store, and stock and payment options are updated accordingly.

## Stock management

If a store has its own stock location, it acts like a small warehouse added to the market's inventory. When calculating availability, the store's stock location is added to the market's stock hierarchy with the highest priority.&#x20;

If the store has no stock location, the market's stock hierarchy (as defined in the related inventory model) is used as a fallback.

This logic lets you check in-store stock first while also making the full market inventory accessible from physical locations — enabling scenarios like endless aisle.

## Payment methods

You can enable specific payment methods for a store. When a store is in scope, only those are returned as available payment methods. If none are configured, the market's payment methods are used as a fallback.

## Shipments

Shipments from store orders where all items are available in the store's stock location and no stock transfers are involved are automatically considered dispatched by the store operator. They require no shipping method and are marked as delivered as soon as the order is placed.

If some items are not available in-store but are in other market stock locations, behavior depends on the selected [inventory strategy](/how-tos/inventory/strategies). For example:

* **Ship from primary** — stock transfers are created from other stock locations to the store's (automatically set as primary). The customer can pick up the missing items once the transfers are complete.
* **Split shipments** — the missing items are shipped to the customer's shipping address.


# Shipments and shipping categories

Shipment creation and splitting logic, stock line items, and how shipping categories affect order fulfillment

<figure><img src="/files/oNBrhsv8wNsODkCTVpx6" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
A shipment groups one or more parcels for delivery to a customer's address. The inventory strategy controls how many shipments an order generates. Shipping categories can further split an order when items require different delivery methods.
{% endhint %}

## Shipments

A [shipment](/core-api-reference/shipments) is a group of one or more parcels ready to be shipped to a customer's address. Every order is associated with two [addresses](/core-api-reference/addresses):

* **Origin address** (FROM) — the stock location or warehouse the items ship from.
* **Shipping address** (TO) — the customer's destination.

The [inventory strategy](/how-tos/inventory/strategies) determines whether and how an order is split and how many shipments are created. The default strategy is **no split**, which always produces a single shipment from a single stock location. With a different strategy, orders can be split into multiple shipments when:

* Items come from more than one stock location.
* Items belong to more than one shipping category.

All necessary resources are automatically generated based on the chosen strategy. If needed, you can still manually create, modify, or delete shipments after the order has been approved.

You can integrate any fulfillment service and provide real-time tracking updates to customers from the associated carrier account.

## Stock line items

[Stock line items](/core-api-reference/stock_line_items) are the SKUs in an order distributed across one or more shipments. When an order is not split, all SKUs belong to a single stock line item. When split, line items are distributed across multiple shipments. A single line item can also be split into more than one stock line item.

You can create new stock line items or modify existing ones as long as the chosen quantity is available in one of the market's inventory stock locations. You can also add stock line items for products not originally part of the order — for example, to include a free gift or replace an unavailable item.

## Shipping categories

[Shipping categories](/core-api-reference/shipping_categories) are one of the reasons an order can be split into multiple shipments. Unless the **no split** strategy is in use, orders containing items from two or more shipping categories are split into one shipment per category.

A shipping category lets you define the specific shipping methods available for its associated SKUs. The category and the shipping zone an item belongs to together determine the delivery options shown to customers before shipment.

Association with a shipping category is mandatory for all SKUs, except those marked as **do not ship**.


# Stock transfers

Moving inventory between stock locations — automatically during order fulfillment or manually to reorganize stock

<figure><img src="/files/m9QmuOEnPJycXqRH64eR" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
A stock transfer moves a quantity of an SKU from one stock location to another. Transfers can be generated automatically by the inventory strategy during fulfillment, or created manually to reorganize stock across locations.
{% endhint %}

## What is a stock transfer?

A [stock transfer](/core-api-reference/stock_transfers) is the process of moving inventory from one stock location to another. It can represent a real physical movement between warehouses or a rearrangement involving retail stores or other virtual stock locations.

A stock transfer moves a quantity of a single SKU from an origin stock location to a destination stock location:

* **Origin stock location** — the associated stock item quantity is *decremented* as soon as the transfer is created.
* **Destination stock location** — the associated stock item quantity is *incremented* once the transfer is completed.

Stock transfers can be generated automatically based on the inventory strategy when fulfilling an order, or manually created outside of the order scope.

### Automatic stock transfers

The [inventory strategy](/how-tos/inventory/strategies) determines how orders are fulfilled. To honor the selected strategy, one or more stock transfers may be necessary.

For example, with the **ship from primary** strategy, if the primary stock location cannot fulfill all SKUs in the order, stock transfers are created from other locations where the items are available to the primary one. Priority between origin locations is set by the inventory model hierarchy. The associated shipment is put *on hold* until all stock transfers are completed.

### Manual stock transfers

Stock transfers can also be created manually outside of the order fulfillment scope — for example, to reorganize inventory across available stock locations. Manual transfers are not associated with any line items or shipments.

When stock transfers are involved in order fulfillment, related shipments are put on hold and the picking process starts automatically. You can also configure all stock transfers to start *on hold* at the inventory model level, requiring manual management of each transfer's status.


# Shipping zones and methods

Defining shipping zones by location and configuring shipping methods with cost structures, availability rules, and weight-based tiers

<figure><img src="/files/qSHyXo4j56gPj3nRqFpg" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
Shipping zones group locations and determine which delivery options are available for a shipping address. Shipping methods define those options, with prices that can be flat, weight-tiered, or fetched from an external service.
{% endhint %}

## Shipping zones

[Shipping zones](/core-api-reference/shipping_zones) are groups of locations within a market. They determine which shipping methods are available for a given shipping address.

Zones are created and filtered using a regular expression to match the country, state, or zip code of an address.

## Shipping methods

[Shipping methods](/core-api-reference/shipping_methods) define the delivery options with prices available to customers. A shipping method not associated with any market, stock location, shipping category, or shipping zone can be set as the [default](/core-api-reference/markets#default-shipping-method) for one or more markets.

### Available shipping methods

Shipping methods are defined by currency and can be restricted to a specific market (in which case the currency is inherited from the market's price list). Delivery options can be further restricted by:

* **Shipping category** — the method is available only if the items belong to a specified shipping category.
* **Shipping zone** — the method is available only if the shipping address belongs to a specified shipping zone.
* **Stock location** — the method is available only if the items ship from a specific stock location.
* **Weight** — the method is available only if the total shipment weight falls within a specified minimum and/or maximum value. The total weight is calculated automatically from the individual weights of the items.

### Shipping method cost

When creating a shipping method, you must set a price used as its fixed cost. You can also define a **free-over amount** — the order total above which shipping becomes free (shipping methods can also be made free through promotions).

Three pricing schemes are supported (default: *flat*):

* **Flat** — a fixed price, set to zero when the order total exceeds the [free-over amount](/core-api-reference/shipping_methods#free-over-amount) (if defined).
* **Weight-tiered** — the price is [tiered](/core-api-reference/shipping_methods#shipping-weight-tiers) based on the total shipment weight. The free-over amount applies regardless of the tier.
* **External** — the price is fetched [from an external service](/core/external-resources/external-shipping-costs), overriding the price set in Commerce Layer.

### Shipping method tiers

You can define up to **5 weight-based tiers** per shipping method. For each tier you must specify:

* An upper limit for the weight value (the unit of weight is inherited from the shipping method).
* The price charged when the total shipment weight is lower than or equal to that limit.

If the upper limit is left empty, the tier is treated as a *beyond* tier — its price applies to all shipments whose weight exceeds the maximum tier's upper limit. If no *beyond* tier is defined, the shipping method's fixed cost is used instead.


# Delivery lead times

Providing customers with estimated delivery time ranges based on stock location and shipping method

<figure><img src="/files/LZsszM3efpVpyrcsVwXh" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
Delivery lead times give customers an estimated arrival window for their shipment. Different lead times can apply to each available delivery option.
{% endhint %}

## What is a delivery lead time?

[Delivery lead times](/core-api-reference/delivery_lead_times) provide customers with an estimated time of arrival range — for example, a shipment arriving in 2-5 days. Since a market can have many stock locations and shipping method options, different delivery estimates can be shown for each available delivery option.


# Shipping carriers

Connecting carrier accounts to markets for rate options, shipping labels, and tracking numbers

<figure><img src="/files/A8wuesFyPnl3jYsOPMCo" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
Multiple carriers can serve the same market. This enables you to always pick the best rate for each shipment.
{% endhint %}

## What is a shipping carrier?

[Shipping carriers](/core-api-reference/carrier_accounts) move parcels from a stock location to the customer's address. You can get shipping rate options for each shipment and select the most suitable one. Shipping labels and tracking numbers can then be assigned to orders before shipment.

You can connect more than one carrier to the same market to get more rate options. Supported carriers include USPS, DHL, UPS, DPD, FedEx, Amazon Services, Asendia, Aramex, and others.


# Parcels, packages, and pickups

Organizing shipment contents into parcels and packages, with parcel line items and carrier pickup scheduling

<figure><img src="/files/vQ2QGwP2PJUFmSj4LM16" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
The physical side of fulfillment: splitting shipments into parcels, packing them into sized boxes, and scheduling carrier pickups.
{% endhint %}

## Parcels

[Parcels](/core-api-reference/parcels) are shipping line items that represent how a shipment is split for delivery. A shipment can be split into two or more parcels, each tracked individually through the carrier integration. Each parcel includes a shipping label and tracking information that customers can use to monitor their shipment.

## Parcel line items

[Parcel line items](/core-api-reference/parcel_line_items) are the individual SKUs within a parcel. If a stock line item is not split, the parcel line items correspond directly to its SKUs. If a stock line item is split, it is distributed across more than one parcel line item.

## Packages

[Packages](/core-api-reference/packages) are physical boxes or packs stored at a stock location, with predefined dimensions (length, width, height) and weight. Each stock location can have its own set of packages. Shipping carriers use these dimensions to calculate shipping rates.

## Pickups

[Pickups](/core-api-reference/pickups) are associated with eligible shipments and defined by a time window — an earliest and latest time at which the package is available for collection. Once created, the carrier's available pickup rates are returned automatically. A rate must then be selected and purchased to schedule the pickup.


# Geocoders

Converting customer addresses into geographic coordinates to power address validation and location-based features

<figure><img src="/files/AoaZzrZizZoSCNSgG10E" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
Attach a geocoder to a market to enable address-to-coordinate conversion across that market's orders. Google and Bing are both supported.
{% endhint %}

## What is a geocoder?

A [geocoder](/core-api-reference/geocoders) converts a text address into geographic coordinates (for example, latitude `43.87913` and longitude `11.10094`). Attaching one to a market enables coordinate lookups for customers' shipping and billing addresses on that mar

ket's orders.

Coordinates can be used to place markers on a map, validate addresses, power location-based promotions, and other location-aware operations. **Google** and **Bing** geocoder integrations are currently supported.


# Payment gateways

Supported payment gateway types and how to assign them to markets

<figure><img src="/files/zMygpFMuNPtdDMVx9VxN" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
Three gateway types — PSD2-ready, external, and manual — can be connected to markets, giving you full control over payment processing per business context.
{% endhint %}

## How payment gateways work

[Payment gateways](/core-api-reference/payment_gateways) allow you to process payments through Commerce Layer's API safely. You can connect different gateways to different markets via the available payment methods. Commerce Layer currently supports PSD2-ready gateways, custom external gateways, and manual gateways.

{% hint style="success" %}
Commerce Layer payments are **idempotent**. Order and payment statuses are guaranteed to remain consistent across multiple updates throughout the whole payment process.
{% endhint %}

Taxes are automatically calculated at checkout based on the price list associated with the market.

### PSD2-ready gateways

[PSD2-ready gateways](/how-tos/placing-orders/payments) are compliant with the PSD2 European regulation, which applies to all credit card payments. They allow you to implement a payment flow that supports SCA (Strong Customer Authentication) and 3DS2 (3D Secure 2) using the gateway's official SDK. Commerce Layer is currently integrated with some of the most popular payment gateways — **Adyen**, **Axerve**, **Braintree**, **Checkout.com**, **Klarna**, **PayPal**, **Satispay**, and **Stripe** — all PSD2-compliant.

### External payment gateways

[External payment gateways](/core/external-resources/external-payment-gateways) allow you to set up and configure payment gateways not integrated with Commerce Layer by default.

You can create an external payment gateway and define custom endpoints responding to the following actions:

* **Authorization** — to authorize a payment source.
* **Capture** — to capture an authorization.
* **Void** — to cancel a payment authorization.
* **Refund** — to refund a captured payment, either totally or partially.
* **Customer token** — to create a customer payment token.

The external endpoint is responsible for the integration with the payment gateway. The payment source associated with the order must be an external payment.

### Manual payment gateways

[Manual payment gateways](/core-api-reference/manual_gateways) are useful for processing wire transfers, cash payments, and other kinds of manual payments. This gateway type is associated with orders as their payment source type. Payments with manual gateways are always authorized.


# Payment methods

The payment source types you can offer per market and how they connect to payment gateways

<figure><img src="/files/0DJw1TIfuBwLyz5OjqQu" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
Each market's checkout payment experience is driven by its payment methods — they determine which gateway processes each payment and what options customers see.
{% endhint %}

## What is a payment method?

[Payment methods](/core-api-reference/payment_methods) are the types of payment sources you can offer in a market or a store. They let you provide different payment options to customers. Payment methods can carry a price charge and must be present before a customer places an order.

Each payment method is associated with a [payment gateway](/data-model/payments-and-tax/payment-gateways). The payment source type used with a payment method must match the parent gateway. You can differentiate the available payment method options by market. Supported payment source types include Adyen, Axerve, Braintree, Checkout.com, credit card, external payment, Klarna, PayPal, Satispay, Stripe, and wire transfer.

A payment method not already associated with a market or a store can be set as the default payment method for one or more markets.


# Tax calculation

How automatic tax calculation works and the calculators, categories, and rules that power it

<figure><img src="/files/lJ18MoZxEhiltMmSweWN" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
Commerce Layer automatically calculates taxes at checkout using a configurable calculator per market — you can use a supported third-party service, an external integration, or define your own rules manually.
{% endhint %}

## Tax calculators

Taxes are automatically calculated at checkout. If the price list associated with a market does not include taxes, the tax is added to the order total and customers are charged. If the price list includes taxes, the tax is only reflected in the order summary. [Tax calculators](/core-api-reference/tax_calculators) use the merchant's address and the shipping address to determine the order's tax rate.

An organization can have one or more tax calculators. You can connect a tax calculator to a market, and all taxes for orders in that market will be calculated automatically. Commerce Layer currently supports **Avalara**, **Stripe Tax**, **TaxJar**, and **Vertex**, plus the option to use a [manual tax calculator](/core-api-reference/manual_tax_calculators) or implement custom logic via [external tax calculators](/core/external-resources/external-tax-calculators). If you use a manual calculator, you must define its tax rules manually — third-party calculators already provide their own rules by default.

## Tax categories

[Tax categories](/core-api-reference/tax_categories) are defined for all SKUs that have special taxation. They are used by the tax calculators that support them — currently Avalara, Stripe Tax, and TaxJar — to determine any reduced tax rate for SKUs.

## Tax rules

[Tax rules](/core-api-reference/tax_rules) are associated with manual calculators. They allow you to define matching rules based on the shipping address, unlike third-party calculators which provide tax rules by default. You can use regular expressions to filter shipping addresses by country, state code, and zip code — the applicable tax rule is then determined by matching the order's shipping address against the defined expressions.


# Anatomy of an order

What makes up an order and how it moves through placement, editing, and fulfillment

<figure><img src="/files/WpthHdkX1N74FKIjESvE" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
An order is a composite resource — from line items and addresses to payment and shipments — that moves through a well-defined lifecycle from draft to fulfilled.
{% endhint %}

## Order structure

An [order](/core-api-reference/orders) can consist of a customer, line items (SKUs, cost of shipping method, cost of payment method, taxes, or gift cards), a billing address, a shipping address, discounts calculated from active promotions, redeemed gift cards, a payment method, and a payment source type. The price of all components is summed up, and the cost of applied discounts and redeemed gift cards is subtracted from the total. The customer then checks out the order and pays the resulting total before shipping commences.

[Line items](/core-api-reference/line_items) that have a frequency are used to automatically generate recurring orders involved in a [subscription process](/how-tos/placing-orders/subscriptions), triggered using a specific order attribute.

## Placing orders

The order placement process is **synchronous** by default. You can force your orders to be placed [asynchronously](/core-api-reference/orders#asynchronous-order-placement) by setting the related flag at the order level.

{% hint style="info" %}
The steps below illustrate a typical order flow from cart to delivery. The exact sequence may vary depending on the use case.
{% endhint %}

* A customer visits a sales channel (either as a registered or unregistered customer).
* The customer selects the items they want to purchase and adds them to the cart (including gift cards).
* The customer applies available discounts from active promotions (optional).
* The shopping cart is a *draft* order.
* Draft orders are labeled *pending* when the customer adds their email address.
* The customer enters their shipping and billing address.
* The customer selects a shipping and payment method defined for their market (a default one may already be set).
* The price of all items in the order is summed up.
* The customer makes the payment using their preferred payment source type.
* In case of asynchronous placement, the order is momentarily put in *placing*.
* The customer's payment is *authorized* and needs to be captured.
* The order can be cancelled before it is *captured* (cancelled orders will have their payment authorization *voided*).
* Before approval, placed orders can still be moved to *editing* status to make last-minute changes (e.g. removing or changing items), as long as the order total after the update does not exceed the authorized amount.
* The order is *approved* and the customer's payment is captured.
* All shipments generated by the approved order are shipped and the order fulfillment status becomes *fulfilled*.

## Order editing

Draft and pending orders are always [editable](/core-api-reference/orders#order-editing) by a sales channel before placement. Once an order is placed but not yet approved, it can be moved to *editing* status by an integration application (for security reasons) via trigger attribute. When an order is in *editing*, it can be updated by the customer on the condition that the changes don't lead to a total that exceeds the previously authorized (or already captured) amount. Once editing is finished, the order must be moved back to *placed* status (again via trigger attribute, only by an integration application), from where it can then be approved.

Discounts from promotions applied at placement time are refreshed during editing. New promotions are not applied. New coupons or gift cards can be added, as long as they were not already present at the time of placement. If the total after editing is less than the authorized amount, the new amount will be captured. If the authorized amount was already captured, a partial refund will be performed. Shipments are rebuilt, so after any editing operation and before exiting editing status, you need to check the available shipping methods again and choose one to reassociate with the order.

Orders can be edited multiple times before approval. Once an editing operation is started, it can't be reverted but can be aborted by cancelling the order.

## Order validation

Automatic validation is performed at the time of order placement. If you need to execute custom validation — for example, to support more complex business logic such as market-specific quantities or SKUs — you can leverage the [external order validation](/core/external-resources/external-order-validation) feature.

## Idempotency

Order status changes are **idempotent**. This means order and payment statuses stay consistent across multiple updates — for example, it's possible to place or cancel an order more than once without worrying about duplicated transactions or other unintended effects.


# Orders management

The order management system and how orders flow from placement to fulfillment and refunds

<figure><img src="/files/I8zag4MHWHznKgqktUPf" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
The OMS centralizes orders from all markets in one place — each order moves through payment and fulfillment statuses that you can customize with options like delayed capture, auto-capture, and partial refunds.
{% endhint %}

## Order management system

Commerce Layer provides an [order management system](https://commercelayer.io/distributed-oms) (OMS) that allows you to manage orders across different statuses in one place. The OMS covers the full process from when a customer places an order to fulfilling it.

You can receive all orders from any supported market and fulfill them in a centralized hub. You can also integrate third-party systems to automate workflows and customize your order management pipeline.

## Order fulfillment

An order is initially created in *draft* status. Draft orders act as shopping carts and become *pending* when the customer adds line items and their email address. All pending orders have a payment status of *unpaid* and a fulfillment status of *unfulfilled*.

The customer adds one or more line items to the cart and selects one of the available shipping methods. Applied discounts and gift cards are subtracted from the order total before checkout. At checkout, the customer enters their billing and shipping address and selects a payment method supported in their market. Existing customers can reuse a payment source from a previous order or choose a new one.

When an order is *placed* (payment successful), its payment status becomes *authorized*. The payment is then *captured* and the amount is debited from the customer's payment source. Before capture, the customer can cancel the order — cancelled orders have their payment authorization *voided* and a payment status of *cancelled*. Captured orders become *approved* and ready for shipment. The fulfillment status becomes *fulfilled* once all shipments are shipped.

By default, payments must be captured before fulfillment can begin. You can override this by allowing [delayed capture](/core-api-reference/payment_methods#capture-options) at the payment method level. You can also unify authorization and capture by enabling the [auto-capture](/how-tos/placing-orders/auto-capture) option to automatically capture payments upon authorization.

A customer can request a [refund](/core-api-reference/refunds) at any point once the payment is captured. You can refund payments partially or fully. The market associated with the order determines the price list, inventory model, payment methods, and all related business rules.


# Returns management

How returns are created, tracked through their lifecycle, and refunded

<figure><img src="/files/nXsonvG4fJAWyh9sPxFz" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
Returns can only be created from fulfilled orders, follow a lifecycle from draft to refunded, and can trigger a partial or full refund without cancelling the original order.
{% endhint %}

## Return management system

Commerce Layer provides a return management system that allows you to manage returns across different statuses in one place. You can handle orders returned for any reason — faulty line items, long delivery times, and so on.

[Returns](/core-api-reference/returns) can only be created from fulfilled orders. Multiple returns can be created from a single order. When a return request is submitted, it is either approved or not. SKUs that are successfully returned can be restocked to the inventory.

## Return fulfillment

Returns are initially created in *draft* status. They become *requested* when a customer requests to return SKUs from a specific order. Requested returns can be *approved* or *cancelled*. An approved return becomes *shipped* once it leaves the origin address (customer address). Once shipped returns reach the specified return location (destination address), their status becomes either *received* (if the return process completed successfully) or *rejected* (e.g. the customer sent back the wrong items). Received returns can be refunded, in which case their status becomes *refunded*. Successfully returned SKUs can be restocked to an inventory location.

## Refund from a return

Once returned items arrive at the destination address, a refund process can be initiated [from the return itself](/core-api-reference/returns#refunding-from-a-return).

<figure><img src="/files/1rEoavDxlxKI5wJ35KUu" alt=""><figcaption></figcaption></figure>

The amount to be refunded must be specified manually — the API computes an estimate based on the price and quantity of the returned items, exposed in a return attribute. By default, the refund is applied to the most recent successful capture associated with the order. If there are multiple captures, you can specify a different one. Starting a refund from a return does not cancel the associated order.


# Subscriptions and order copies

How subscriptions work, how automatic and manual order copies are generated, and how recurring orders are managed

{% hint style="info" icon="lightbulb" %}
Subscriptions generate recurring target orders from a source order — automatically via a subscription model with recurring order copies, or manually via simple order copies that clone the source order in full.
{% endhint %}

## What is an ecommerce subscription service?

A subscription-based ecommerce is a business model that allows customers to subscribe to products or services on a recurring basis in exchange for regular payments.

The value of a subscription is not only in the resultant predictable revenue. Subscriptions help your business increase acquisition and retention, make purchase forecasting easier, and are a real opportunity to build a stronger brand community.

## How Commerce Layer handles subscriptions

Commerce Layer lets you offer subscriptions to registered customers. Subscriptions are defined by market and rely on the [order subscription](/core-api-reference/order_subscriptions) resource. Starting from a source order, scheduled target orders are created. How this happens and the other resources involved depend on how you decide to handle subscription management:

* **Automatic subscriptions** — a subscription model must be associated with the market. One or more order subscriptions with related order subscription items are generated from the source order's line items that have a frequency set. Recurring order copies are used to generate recurring target orders.
* **Manual subscriptions** — can be used in markets with no subscription model associated, for orders that don't contain any line items with a frequency set. One order subscription is generated from the source order, which is entirely cloned. Order copies are used to generate recurring target orders.

## Automatic subscriptions

One or more order subscriptions are automatically generated at the order level via trigger attribute, based on the strategy specified in the subscription model associated with the market and on the source order's line items for which you've set a frequency. This way you can activate subscriptions that exclude some of the source order's items (the ones without a frequency) and allow different subscription logic — for example, different frequencies for different items — within the same source order.

<figure><img src="/files/jsOVidT9aorHiQNOpiOG" alt=""><figcaption></figcaption></figure>

### What is a subscription model?

A [subscription model](/core-api-reference/subscription_models) can be optionally associated with a market to determine how automatic order subscriptions using recurring order copies are generated. It defines which subscription frequencies are available for the market — enabling sales channels to specify one of them for order line items — and sets the subscription strategy, one of:

* **By frequency** — as many order subscriptions as the different frequencies specified for the source order's line items are generated, each with the related order subscription items (default strategy).
* **By line items** — an order subscription is generated for each source order line item that has a frequency, each with its related order subscription item.

At the subscription model level, you can decide whether the created subscriptions will be activated (default) or not — considering the source order as the first run — and whether they will be cancelled if the source order is cancelled (not the default behavior).

### How to automatically generate order subscriptions

If a subscription model is associated with the market, the necessary order subscriptions are automatically generated based on the order's line items for which you've specified a frequency, according to the strategy set at the subscription model level. The related order subscription items are also created and associated with the generated order subscriptions.

The [automatic generation process](/how-tos/placing-orders/subscriptions) is triggered by using a specific attribute — giving you full control over when to do it, usually as soon as the source order is placed or shortly after. The source order's customer email is stored, that order is considered the subscription's first run, and the generated order subscriptions are activated (unless specified otherwise at the subscription model level).

Order subscription operations rely on [recurring order copies](#how-recurring-order-copies-work). For each automatically generated order subscription, some source order information is copied (e.g. addresses, customer payment source), the related order subscription items are created and associated with the order subscriptions, and — if the recurring order copy is successful — the target order is placed.

Between each run you can [edit the subscription](/how-tos/placing-orders/subscriptions/updating-the-subscriptions) (e.g. changing its frequency, expiration date, status, or associated order subscription items) to dynamically manage the next occurrences.

### What are order subscription items?

[Order subscription items](/core-api-reference/order_subscription_items) can be of type SKU, bundle, or adjustment and are used to generate the target order's line items involved in the subscription process. Like line items, they have a quantity and a unit price (inherited from the source order's line items, whether it's the default price or computed according to a price frequency tier).

If the subscription strategy is *by frequency*, as many order subscription items as the source order's line items with that specific frequency are generated for each order subscription. If the strategy is *by line items*, one order subscription item only is generated per order subscription.

Order subscription items can be created, updated, and deleted, giving you full control over the next subscription occurrences — for example, adding or removing items for custom curation, or changing an item's quantity or unit price.

### How recurring order copies work

[Recurring order copies](/core-api-reference/recurring_order_copies) are a type of order factory that generates a target order from the associated source order and order subscription (and related order subscription items), repeating it according to the frequency specified for the items — which must be one of those available for the market as set at the subscription model level.

When copying an order recursively, the source order is never reused to generate subsequent runs — those are built entirely from the associated order subscription and its order subscription items.

Recurring order copies cannot be used standalone. They must always be associated with an [automatic order subscription](/core-api-reference/order_subscriptions#automatic-order-subscription-generation).

## Manual subscriptions

A unique order subscription is manually generated starting from a source order that doesn't contain any line item with a frequency, in a market with no subscription model associated. All the information and line items of the source order are copied to generate identical target orders, which are then scheduled for placement with a specified frequency set directly on the order subscription.

<figure><img src="/files/P9rcdHLQh3S8L9stPhrO" alt=""><figcaption></figcaption></figure>

### How to manually generate order subscriptions

A [manually generated](/core-api-reference/order_subscriptions#manual-order-subscription-generation) order subscription can be created on top of a given source order and allows repeating it according to a specified frequency.

By default, this type of subscription activates from a *placed* source order and stores the associated customer email. That order is considered the subscription's first run and all subsequent ones are scheduled from it. If you need full control over the subscription process, you can override the default behavior and extend order subscription creation to source orders that are not yet placed — in that case, you need to manually set the start time and remember to activate it.

Order subscription operations rely on [order copies](#how-order-copies-work). When an order subscription is created manually, the source order is copied, the related target order is created, and — at the end of the process — an attempt to place it is performed. You can choose not to follow this default and place the target order manually instead. This is useful when you need to edit the next subscription occurrence (e.g. adding or removing line items for custom curation) and allows you to dynamically change the subscription content on each run.

Order subscriptions that use recurring order copies can also be generated manually — you just need to set the relationship with an existing subscription model and a source order, create and associate the order subscription items, and specify the customer payment source.

### How order copies work

[Order copies](/core-api-reference/order_copies) are a type of order factory that generates a full copy of a source order — including all associated line items, line item options, and addresses — into a target order. The payment source is copied only if it is stored within the customer wallet (i.e. reusable).

When copying an order you can set different options for how the process is performed:

* **Place target order** — the target order is placed at the end of the process (if possible).
* **Cancel source order** — the source order is cancelled at the end of the process.

Order copies can be used standalone — for example, to provide *buy-it-again* options to customers, or any time you need to use an existing order as a template — or generated recursively as part of an order subscription.

## Monitoring the process

Both recurring and simple order copying are asynchronous processes. You can check whether the copy is *pending*, *in progress*, *failed*, or *completed* by inspecting the order copy status.

## Promotions and discounts

Recurring order copies never compute promotions and gift cards. You can apply promotions to the source order only — not to the automatically generated recurring target orders. To apply a discount based on the subscription frequency, you can set price frequency tiers or add order subscription items of type adjustment with a negative unit amount.

Order copies create *frozen* copies of the source order, meaning promotion and discount line items are copied as-is without being recomputed. A recalculation occurs only if the target order is edited (e.g. by adding or removing line items).

## Reusing the payment source

Except for wire transfers, automatic target order placement can only succeed if the source order comes with a payment source saved in the customer wallet. For both subscription types, if the source order's payment source is not reusable, the order copy or recurring order copy fails, the target order remains pending, the error log records an error, and the error count is incremented.

## Rebuilding the shipments

Since product availability across stock locations may have changed by the time the target order is placed, shipments are rebuilt for both subscription types — based on order subscription items for recurring order copies, or cloned line items for simple order copies — and the first available shipping method is used. If any items have gone out of stock, the order copy or recurring order copy fails, the error log records an error, and the error count is incremented.

## Subscriptions expiration

Active order subscriptions can be *deactivated* (temporarily suspended) or *cancelled*. An optional expiration date can always be defined if needed.

## Subscriptions errors and retry policy

Subscriptions currently have no automatic retry policy. An error counter is available and incremented whenever the related order copy fails — for any reason — but the subscription remains active. You can always verify whether the last run was successful. If not, inspect the associated order copy's error log to fix any missing or incorrect data and manually place the order.

As a best practice, attach webhooks on order subscription, recurring order copy, and order copy events to react promptly when something unexpected happens.

## Available payment gateways

Since the success of order copies depends on whether the source order's payment source is saved in the customer wallet, subscriptions are available for payment gateways that support reusable payment sources — currently Adyen, Braintree, Stripe, and any external gateways with a properly configured token endpoint.


# Promotions and gift cards

The promotion types available, how activation rules work, and how gift cards can be used as a payment method

<figure><img src="/files/QrlAnyrGvHpvyy6XiJu1" alt=""><figcaption></figcaption></figure>

{% hint style="info" icon="lightbulb" %}
Promotions and gift cards are two separate but complementary discount mechanisms — promotions reduce order amounts based on configurable rules, while gift cards act as a pre-purchased payment source.
{% endhint %}

## Promotions

[Promotions](/core-api-reference/promotions) allow you to offer special discounts to customers. Commerce Layer currently supports the following promotion types:

* **Percentage Discount** — adds a percentage discount to the order subtotal (if associated with an SKU list, the discount applies only to SKUs in that list).
* **Free Shipping** — sets the shipping amount to zero.
* **Fixed Amount** — adds a fixed amount discount to the order.
* **Free Gift** — sets to zero the price of SKUs belonging to a specific list.
* **Fixed Price** — imposes a fixed price for SKUs belonging to a specific list.
* **Buy X Pay Y** — offers a discount corresponding to X-Y units of a product for free for any X units of the same product added to the order (associated with an SKU list, and can also be used in *cheapest free* mode).
* **Flex Promotion** — used in conjunction with the [Rules Engine](#rules-engine) to apply discounts based on fully custom order rules.

Promotions can be defined by currency or restricted to a market (in the latter case the currency is inherited from the market's price list). Commerce Layer also lets you integrate any promotional engine not supported by default via [external promotions](/core/external-resources/external-promotions). Every promotion is configured with [activation rules](#activation-rules) that must be satisfied before the discount is applied — these can include market, time range, order amount, coupon codes, and more.

Some promotions can be reserved for specific customers — for example, via a VIP or private sales model where only customers belonging to a specific group have access to the promotions in a given market and get the associated price list. Alternatively, you can associate customers with specific tags and trigger different promotions based on those tags.

When multiple promotions are active on the same order at the same time, they are applied in a default sequence [based on promotion type](/core-api-reference/promotions#priority-and-order-of-application). You can change that order by specifying a custom *priority*. Promotions can also be marked as *exclusive* so that, if triggered, no other concurrent promotion is applied.

## Activation rules

Promotions are enabled by default and can be disabled and re-enabled at any time.

[Activation rules](/core-api-reference/promotion_rules) are the conditions that must be satisfied before an enabled promotion is triggered. If no activation rule is associated with an active promotion, the discount is applied to all orders in scope. Available rules include:

* **Time range of validity** — the activation and expiration time of the promotion.
* **Currency / Market** — the currency of the promotion (inherited from the price list of the associated market, if defined).
* **Total usage limit** — the total number of times the promotion can be applied.
* **Order amount** — the minimum order total required for the promotion to activate.
* **SKU list** — the SKUs an order must contain for the promotion to activate.
* **Coupon** — coupon codes that must be applied for the promotion to activate.
* **Custom filters** — based on specific conditions that the order or its associated resources must meet.

You can update the rules for any promotion at any time. For the SKU list rule, you can choose whether the promotion activates if the order contains *any* SKUs in the list or *all* of them. For an SKU list rule to apply to bundles, the two resources must share the same SKU list — in that case there is no partial SKU matching.

{% hint style="info" %}
Promotions based on coupons are **unlimited**. Other promotion types are subject to a limit of **10 active promotions per organization** (this may vary depending on your plan). If more than 10 are active at the same time, only the 10 with the highest priority are applied.
{% endhint %}

## Rules engine

The [Rules Engine](https://docs.commercelayer.io/rules-engine/) is available for enterprise customers. It enables you to define almost any kind of promotional rule — from the simplest to the most complex — using a DSL with conditions and actions.

To use the Rules Engine with promotions, you create a [flex promotion](/core-api-reference/flex_promotions) and define the order rules at your leisure. Supported [action types](/rules-engine/actions/types) include:

* **Percentage** — applies a percentage discount to the amount of the selected field.
* **Fixed amount** — applies a fixed discount to the unit amount of the selected field.
* **Fixed price** — overwrites the unit amount of the selected field with the specified value.
* **Free gift** — applies a 100% discount to line items added to the cart as free gifts.
* **Buy X pay Y** — if the quantity of the selected items is a multiple of X, only the same multiple of Y units are considered for the total price computation.
* **Every X discount Y** — applies a fixed amount discount of value Y for each interval defined by the value X on the amount of a specific field.

The discount is automatically applied to any order that satisfies the given conditions. You can also [validate a flex promotion](/rules-engine/check-and-validation) against a specific order to preview how the rules would apply before going live.

## Gift cards

[Gift cards](/core-api-reference/gift_cards) are a unique type of payment method. Customers can purchase gift cards and use them to pay for an order. All gift cards must be activated before use. There are two types:

* **Rechargeable** — card balance can be used and reloaded at any time.
* **Non-rechargeable** — card balance cannot be reloaded.

Both types can also be:

* **Single-use** — card balance can only be used once.
* **Multi-use** — card balance can be used multiple times until no balance remains.

The availability or usage of gift cards can be restricted by associating them with one or more markets. The market's currency must match the card's currency.

## Gift card recipients

[Gift card recipients](/core-api-reference/gift_card_recipients) allow you to associate a recipient with a purchased gift card. When a customer purchases a gift card, they may want to send it to someone — you can integrate an email or transaction service to send the gift card digitally, or physically print and ship it. When a gift card is redeemed, the recipient is associated with the customer that placed the order.


# Introduction

A detailed list of all Commerce Layer core resources

Commerce Layer is a flexible commerce API that features **400+ endpoints**. This is the detailed reference where you can explore the complete list of our core resources.

## How it works

For each single resource you can find:

* The **resource** object and its fields, attributes, and relationships.
* The allowed **CRUD** operations you can perform on the related endpoint with basic examples of the request/response format.

{% hint style="success" icon="robot" %}
Commerce Layer documentation is [LLM-ready](/#llm-friendly)! To feed the knowledge base into your own LLM, read [this file](https://docs.commercelayer.io/llms.txt).
{% endhint %}

## More to read

See our [Getting started](https://docs.commercelayer.io/developers/) guide for basic information on how to [fetch](https://docs.commercelayer.io/developers/fetching-resources), [create](https://docs.commercelayer.io/developers/creating-resources), [update](https://docs.commercelayer.io/developers/updating-resources) and [delete](https://docs.commercelayer.io/developers/deleting-resources) resources or any other instruction you need to interact with our API.

Check our [changelog](https://docs.commercelayer.io/changelog/) to stay up-to-date with any changes we make on the APIs, apps, and open-source projects (including versioning, product releases, new features, and general improvements).

Read our [how-tos](https://docs.commercelayer.io/developers/v/how-tos/) for step-by-step tutorials and best practices on how to handle the most common ecommerce scenarios.

Try out our [Metrics API](https://docs.commercelayer.io/metrics/) and see how it can enable you to gather and aggregate useful data that you can leverage to measure the health and performance of your ecommerce business.

Do you need to manage provisioning tasks programmatically, extend our Dashboard, or even build your own? Leverage our [Provisioning API](https://docs.commercelayer.io/provisioning/) and exercise greater control over your organizational structure and user roles.

Would you like to benefit from a DSL that enables you to define promotional rules? If you're an enterprise customer, you can ask to test our [Rules Engine](https://docs.commercelayer.io/rules-engine/) and start setting up almost any kind of [promotions](/core-api-reference/flex_promotions) to boost your sales, from the simplest to the most complex.


# Addresses

The address object and the allowed CRUD operations on the related resource endpoint

Addresses can be associated with orders as their shipping or billing addresses. Add a Google or Bing geocoder to a market if you want its addresses to be automatically geocoded. Customers can save their most-used addresses in their address books (as customer addresses).


# The address object

A comprehensive list of the address resource's attributes and relationships

An address object is returned as part of the response body of each successful list, retrieve, create or update API call to the `/api/addresses` endpoint.

## Fields

| Field                            | Type      | Description                                                                                                                                                                                         |
| -------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **type**                         | `string`  | `addresses`                                                                                                                                                                                         |
| **id**                           | `string`  | The address unique identifier                                                                                                                                                                       |
| links.**self**                   | `string`  | The address endpoint URL                                                                                                                                                                            |
| attributes.**business**          | `boolean` | Indicates if it's a business or a personal address.                                                                                                                                                 |
| attributes.**first\_name**       | `string`  | Address first name (personal).                                                                                                                                                                      |
| attributes.**last\_name**        | `string`  | Address last name (personal).                                                                                                                                                                       |
| attributes.**company**           | `string`  | Address company name (business).                                                                                                                                                                    |
| attributes.**full\_name**        | `string`  | Company name (business) of first name and last name (personal).                                                                                                                                     |
| attributes.**line\_1**           | `string`  | Address line 1, i.e. Street address, PO Box.                                                                                                                                                        |
| attributes.**line\_2**           | `string`  | Address line 2, i.e. Apartment, Suite, Building.                                                                                                                                                    |
| attributes.**city**              | `string`  | Address city.                                                                                                                                                                                       |
| attributes.**zip\_code**         | `string`  | ZIP or postal code.                                                                                                                                                                                 |
| attributes.**state\_code**       | `string`  | State, province or region code.                                                                                                                                                                     |
| attributes.**country\_code**     | `string`  | The international 2-letter country code as defined by the ISO 3166-1 standard.                                                                                                                      |
| attributes.**phone**             | `string`  | Phone number (including extension).                                                                                                                                                                 |
| attributes.**full\_address**     | `string`  | Compact description of the address location, without the full name.                                                                                                                                 |
| attributes.**name**              | `string`  | Compact description of the address location, including the full name.                                                                                                                               |
| attributes.**email**             | `string`  | Email address.                                                                                                                                                                                      |
| attributes.**notes**             | `string`  | A free notes attached to the address. When used as a shipping address, this can be useful to let the customers add specific delivery instructions.                                                  |
| attributes.**lat**               | `float`   | The address geocoded latitude. This is automatically generated when creating a shipping/billing address for an order and a valid geocoder is attached to the order's market.                        |
| attributes.**lng**               | `float`   | The address geocoded longitude. This is automatically generated when creating a shipping/billing address for an order and a valid geocoder is attached to the order's market.                       |
| attributes.**is\_localized**     | `boolean` | Indicates if the latitude and logitude are present, either geocoded or manually updated.                                                                                                            |
| attributes.**is\_geocoded**      | `boolean` | Indicates if the address has been successfully geocoded.                                                                                                                                            |
| attributes.**provider\_name**    | `string`  | The geocoder provider name (either Google or Bing).                                                                                                                                                 |
| attributes.**map\_url**          | `string`  | The map url of the geocoded address (if geocoded).                                                                                                                                                  |
| attributes.**static\_map\_url**  | `string`  | The static map image url of the geocoded address (if geocoded).                                                                                                                                     |
| attributes.**billing\_info**     | `string`  | Customer's billing information (i.e. VAT number, codice fiscale).                                                                                                                                   |
| attributes.**\_add\_tags**       | `string`  | Comma separated list of tags to be added. Duplicates, invalid and non existing ones are discarded. Cannot be passed by sales channels.                                                              |
| attributes.**\_remove\_tags**    | `string`  | Comma separated list of tags to be removed. Duplicates, invalid and non existing ones are discarded. Cannot be passed by sales channels.                                                            |
| attributes.**created\_at**       | `string`  | Time at which the resource was created.                                                                                                                                                             |
| attributes.**updated\_at**       | `string`  | Time at which the resource was last updated.                                                                                                                                                        |
| attributes.**reference**         | `string`  | A string that you can use to add any external identifier to the resource. This can be useful for integrating the resource to an external system, like an ERP, a marketing tool, a CRM, or whatever. |
| attributes.**reference\_origin** | `string`  | Any identifier of the third party system that defines the reference code.                                                                                                                           |
| attributes.**metadata**          | `object`  | Set of key-value pairs that you can attach to the resource. This can be useful for storing additional information about the resource in a structured format.                                        |
| relationships.**geocoder**       | `object`  | The geocoder attached to the address, to be used for geocoding.                                                                                                                                     |
| relationships.**events**         | `array`   | The associated events.                                                                                                                                                                              |
| relationships.**tags**           | `array`   | The associated tags. Cannot be passed by sales channels.                                                                                                                                            |
| relationships.**event\_stores**  | `array`   | The associated event stores.                                                                                                                                                                        |
| meta.**mode**                    | `string`  | The resource environment (can be one of `test` or `live`)                                                                                                                                           |


# Create an address

How to create an address via API

To [create](https://docs.commercelayer.io/core/creating-resources) a new address, send a `POST` request to the `/api/addresses` endpoint, passing the resource arguments in the request body.

## Request

**POST** <https://yourdomain.commercelayer.io/api/addresses>

### Arguments

| Body Parameter                   | Type      | Required                          |
| -------------------------------- | --------- | --------------------------------- |
| **type**                         | `string`  | Required                          |
| attributes.**business**          | `boolean` | Optional, default is 'false'      |
| attributes.**first\_name**       | `string`  | Required if 'business' is 'false' |
| attributes.**last\_name**        | `string`  | Required if 'business' is 'false' |
| attributes.**company**           | `string`  | Required if 'business' is 'true'  |
| attributes.**line\_1**           | `string`  | Required                          |
| attributes.**line\_2**           | `string`  | Optional                          |
| attributes.**city**              | `string`  | Required                          |
| attributes.**zip\_code**         | `string`  | Required, but for some countries  |
| attributes.**state\_code**       | `string`  | Optional                          |
| attributes.**country\_code**     | `string`  | Required                          |
| attributes.**phone**             | `string`  | Required                          |
| attributes.**email**             | `string`  | Optional                          |
| attributes.**notes**             | `string`  | Optional                          |
| attributes.**lat**               | `float`   | Optional                          |
| attributes.**lng**               | `float`   | Optional                          |
| attributes.**billing\_info**     | `string`  | Optional                          |
| attributes.**reference**         | `string`  | Optional                          |
| attributes.**reference\_origin** | `string`  | Optional                          |
| attributes.**metadata**          | `object`  | Optional                          |
| relationships.**geocoder**       | `object`  | Optional                          |
| relationships.**tags**           | `array`   | Optional                          |

### Example

{% tabs %}
{% tab title="Request" %}
The following request creates a new address:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/addresses' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "addresses",
    "attributes": {
      "first_name": "John",
      "last_name": "Smith",
      "company": "The Red Brand Inc.",
      "line_1": "2883 Geraldine Lane",
      "city": "New York",
      "zip_code": "10013",
      "country_code": "US",
      "phone": "(212) 646-338-1228"
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "addresses",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN"
    },
    "attributes": {
      "business": false,
      "first_name": "John",
      "last_name": "Smith",
      "company": "The Red Brand Inc.",
      "full_name": "John Smith",
      "line_1": "2883 Geraldine Lane",
      "line_2": "Apt.23",
      "city": "New York",
      "zip_code": "10013",
      "state_code": "NY",
      "country_code": "US",
      "phone": "(212) 646-338-1228",
      "full_address": "2883 Geraldine Lane Apt.23, 10013 New York NY (US) (212) 646-338-1228",
      "name": "John Smith, 2883 Geraldine Lane Apt.23, 10013 New York NY (US) (212) 646-338-1228",
      "email": "john@example.com",
      "notes": "Please ring the bell twice",
      "lat": 40.6971494,
      "lng": -74.2598672,
      "is_localized": true,
      "is_geocoded": true,
      "provider_name": "google",
      "map_url": "https://www.google.com/maps/search/?api=1&query=40.6971494,-74.2598672",
      "static_map_url": "https://maps.googleapis.com/maps/api/staticmap?center=40.6971494,-74.2598672&size=640x320&zoom=15",
      "billing_info": "VAT ID IT02382940977",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "geocoder": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/relationships/geocoder",
          "related": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/geocoder"
        }
      },
      "events": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/relationships/events",
          "related": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/events"
        }
      },
      "tags": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/relationships/tags",
          "related": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/tags"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# List all addresses

How to fetch a collection of addresses via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a collection of addresses, send a `GET` request to the `/api/addresses` endpoint.

## Request

**GET** <https://yourdomain.commercelayer.io/api/addresses>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches a collection of addresses:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/addresses/' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of resource objects:

```json
{
  "data": [
    {
      "id": "XAyRWNUzyN",
      "type": "addresses",
      "links": {
        "self": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN"
      },
      "attributes": {
        "business": false,
        "first_name": "John",
        "last_name": "Smith",
        "company": "The Red Brand Inc.",
        "full_name": "John Smith",
        "line_1": "2883 Geraldine Lane",
        "line_2": "Apt.23",
        "city": "New York",
        "zip_code": "10013",
        "state_code": "NY",
        "country_code": "US",
        "phone": "(212) 646-338-1228",
        "full_address": "2883 Geraldine Lane Apt.23, 10013 New York NY (US) (212) 646-338-1228",
        "name": "John Smith, 2883 Geraldine Lane Apt.23, 10013 New York NY (US) (212) 646-338-1228",
        "email": "john@example.com",
        "notes": "Please ring the bell twice",
        "lat": 40.6971494,
        "lng": -74.2598672,
        "is_localized": true,
        "is_geocoded": true,
        "provider_name": "google",
        "map_url": "https://www.google.com/maps/search/?api=1&query=40.6971494,-74.2598672",
        "static_map_url": "https://maps.googleapis.com/maps/api/staticmap?center=40.6971494,-74.2598672&size=640x320&zoom=15",
        "billing_info": "VAT ID IT02382940977",
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": "ANY-EXTERNAL-REFEFERNCE",
        "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
        "metadata": {
          "foo": "bar"
        }
      },
      "relationships": {
        "geocoder": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/relationships/geocoder",
            "related": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/geocoder"
          }
        },
        "events": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/relationships/events",
            "related": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/events"
          }
        },
        "tags": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/relationships/tags",
            "related": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/tags"
          }
        },
        "event_stores": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/relationships/event_stores",
            "related": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/event_stores"
          }
        }
      },
      "meta": {
        "mode": "test",
        "organization_id": "xRRkjDFafe",
        "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
      }
    },
    {
      "other": "... 9 addresses (first page)"
    }
  ],
  "meta": {
    "record_count": 140,
    "page_count": 14
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/addresses?page[number]=1&page[size]=10",
    "next": "https://yourdomain.commercelayer.io/api/addresses?page[number]=2&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/addresses?page[number]=14&page[size]=10"
  }
}
```

{% endtab %}
{% endtabs %}

Remember that when you fetch a list of resources you get [paginated](https://docs.commercelayer.io/core/pagination) result.

### Sortable fields

The list of addresses can be [sorted](https://docs.commercelayer.io/core/sorting-results) by the following fields:

#### Attributes

* `city`
* `state_code`
* `country_code`
* `id`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`

### Filterable fields

The list of addresses can be [filtered](https://docs.commercelayer.io/core/filtering-data) by the following fields:

#### Attributes

* `business`
* `first_name`
* `last_name`
* `company`
* `line_1`
* `line_2`
* `city`
* `zip_code`
* `state_code`
* `country_code`
* `phone`
* `email`
* `notes`
* `lat`
* `lng`
* `billing_info`
* `id`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`
* `metadata`

#### Relationships

* `events`
* `tags`


# Retrieve an address

How to fetch a specific address via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a single address, send a `GET` request to the `/api/addresses/:id` endpoint, where `id` is the ID of the resource that you want to retrieve.

## Request

**GET** <https://yourdomain.commercelayer.io/api/addresses/:id>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches the address identified by the ID "XAyRWNUzyN":

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a single resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "addresses",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN"
    },
    "attributes": {
      "business": false,
      "first_name": "John",
      "last_name": "Smith",
      "company": "The Red Brand Inc.",
      "full_name": "John Smith",
      "line_1": "2883 Geraldine Lane",
      "line_2": "Apt.23",
      "city": "New York",
      "zip_code": "10013",
      "state_code": "NY",
      "country_code": "US",
      "phone": "(212) 646-338-1228",
      "full_address": "2883 Geraldine Lane Apt.23, 10013 New York NY (US) (212) 646-338-1228",
      "name": "John Smith, 2883 Geraldine Lane Apt.23, 10013 New York NY (US) (212) 646-338-1228",
      "email": "john@example.com",
      "notes": "Please ring the bell twice",
      "lat": 40.6971494,
      "lng": -74.2598672,
      "is_localized": true,
      "is_geocoded": true,
      "provider_name": "google",
      "map_url": "https://www.google.com/maps/search/?api=1&query=40.6971494,-74.2598672",
      "static_map_url": "https://maps.googleapis.com/maps/api/staticmap?center=40.6971494,-74.2598672&size=640x320&zoom=15",
      "billing_info": "VAT ID IT02382940977",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "geocoder": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/relationships/geocoder",
          "related": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/geocoder"
        }
      },
      "events": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/relationships/events",
          "related": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/events"
        }
      },
      "tags": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/relationships/tags",
          "related": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/tags"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Update an address

How to update an existing address via API

To [update](https://docs.commercelayer.io/core/updating-resources) an existing address, send a `PATCH` request to the `/api/addresses/:id` endpoint, where `id` is the ID of the resource that you want to update.

Here below the list of all the possible arguments that you can pass with the request body.

## Request

**PATCH** <https://yourdomain.commercelayer.io/api/addresses/:id>

### Arguments

| Body Parameter                   | Type      | Required |
| -------------------------------- | --------- | -------- |
| **type**                         | `string`  | Required |
| **id**                           | `string`  | Required |
| attributes.**business**          | `boolean` | Optional |
| attributes.**first\_name**       | `string`  | Optional |
| attributes.**last\_name**        | `string`  | Optional |
| attributes.**company**           | `string`  | Optional |
| attributes.**line\_1**           | `string`  | Optional |
| attributes.**line\_2**           | `string`  | Optional |
| attributes.**city**              | `string`  | Optional |
| attributes.**zip\_code**         | `string`  | Optional |
| attributes.**state\_code**       | `string`  | Optional |
| attributes.**country\_code**     | `string`  | Optional |
| attributes.**phone**             | `string`  | Optional |
| attributes.**email**             | `string`  | Optional |
| attributes.**notes**             | `string`  | Optional |
| attributes.**lat**               | `float`   | Optional |
| attributes.**lng**               | `float`   | Optional |
| attributes.**billing\_info**     | `string`  | Optional |
| attributes.**\_add\_tags**       | `string`  | Optional |
| attributes.**\_remove\_tags**    | `string`  | Optional |
| attributes.**reference**         | `string`  | Optional |
| attributes.**reference\_origin** | `string`  | Optional |
| attributes.**metadata**          | `object`  | Optional |
| relationships.**geocoder**       | `object`  | Optional |
| relationships.**tags**           | `array`   | Optional |

### Example

{% tabs %}
{% tab title="Request" %}
The following request updates the address identified by the ID "XAyRWNUzyN":

```shell
curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "addresses",
    "id": "xYZkjABcde",
    "attributes": {
      "line_2": "Apt.23"
    },
    "relationships": {
      "geocoder": {
        "data": {
          "type": "geocoders",
          "id": "ABCRtyUpBa"
        }
      }
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the updated resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "addresses",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN"
    },
    "attributes": {
      "business": false,
      "first_name": "John",
      "last_name": "Smith",
      "company": "The Red Brand Inc.",
      "full_name": "John Smith",
      "line_1": "2883 Geraldine Lane",
      "line_2": "Apt.23",
      "city": "New York",
      "zip_code": "10013",
      "state_code": "NY",
      "country_code": "US",
      "phone": "(212) 646-338-1228",
      "full_address": "2883 Geraldine Lane Apt.23, 10013 New York NY (US) (212) 646-338-1228",
      "name": "John Smith, 2883 Geraldine Lane Apt.23, 10013 New York NY (US) (212) 646-338-1228",
      "email": "john@example.com",
      "notes": "Please ring the bell twice",
      "lat": 40.6971494,
      "lng": -74.2598672,
      "is_localized": true,
      "is_geocoded": true,
      "provider_name": "google",
      "map_url": "https://www.google.com/maps/search/?api=1&query=40.6971494,-74.2598672",
      "static_map_url": "https://maps.googleapis.com/maps/api/staticmap?center=40.6971494,-74.2598672&size=640x320&zoom=15",
      "billing_info": "VAT ID IT02382940977",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "geocoder": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/relationships/geocoder",
          "related": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/geocoder"
        }
      },
      "events": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/relationships/events",
          "related": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/events"
        }
      },
      "tags": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/relationships/tags",
          "related": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/tags"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Delete an address

How to delete an existing address via API

To [delete](https://docs.commercelayer.io/core/deleting-resources) an address, send a `DELETE` request to the `/api/addresses/:id` endpoint, where `id` is the id of the address that you want to delete.

## Request

**DELETE** <https://yourdomain.commercelayer.io/api/addresses/:id>

### Example

{% tabs %}
{% tab title="Request" %}
The following request tries to delete the address identified by the ID "XAyRWNUzyN":

```shell
curl -g -X DELETE \
  'https://yourdomain.commercelayer.io/api/addresses/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `204 No Content` status code.
{% endtab %}
{% endtabs %}


# Adjustments

The adjustment object and the allowed CRUD operations on the related resource endpoint

Adjustments are arbitrary objects that can be used to change the total amount of an order by any value, either greater or lower than zero.

To add an adjustment to an order, you first need to create the adjustment and then create a line item that references it.

Unless you set the `distribute_discount` attribute to `false` (default is `true`) at the single adjustment level, negative adjustment amounts are distributed as discounts on all the [taxable items](/core-api-reference/orders#taxable-items) of the order based on the ratio between the line item amount and the sum of the amounts of all the line items involved.

{% hint style="info" %}
For negative adjustment amounts to be effective, they must be added to an order that already has a total amount greater than zero (i.e. after having added one or more line items of type `skus` and/or `bundles`).
{% endhint %}

{% hint style="warning" %}
Negative adjustment amounts are applied **before** any kind of [promotion](/core-api-reference/promotions) and/or [gift cards](/core-api-reference/gift_cards) used to pay for the associated order (e.g. if you add an adjustment that brings the total order amount to zero, no promotion will have any effect).
{% endhint %}


# The adjustment object

A comprehensive list of the adjustment resource's attributes and relationships

An adjustment object is returned as part of the response body of each successful list, retrieve, create or update API call to the `/api/adjustments` endpoint.

## Fields

| Field                               | Type      | Description                                                                                                                                                                                         |
| ----------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **type**                            | `string`  | `adjustments`                                                                                                                                                                                       |
| **id**                              | `string`  | The adjustment unique identifier                                                                                                                                                                    |
| links.**self**                      | `string`  | The adjustment endpoint URL                                                                                                                                                                         |
| attributes.**name**                 | `string`  | The adjustment name.                                                                                                                                                                                |
| attributes.**currency\_code**       | `string`  | The international 3-letter currency code as defined by the ISO 4217 standard.                                                                                                                       |
| attributes.**amount\_cents**        | `integer` | The adjustment amount, in cents.                                                                                                                                                                    |
| attributes.**amount\_float**        | `float`   | The adjustment amount, float.                                                                                                                                                                       |
| attributes.**formatted\_amount**    | `string`  | The adjustment amount, formatted.                                                                                                                                                                   |
| attributes.**distribute\_discount** | `boolean` | Indicates if negative adjustment amount is distributed for tax calculation.                                                                                                                         |
| attributes.**created\_at**          | `string`  | Time at which the resource was created.                                                                                                                                                             |
| attributes.**updated\_at**          | `string`  | Time at which the resource was last updated.                                                                                                                                                        |
| attributes.**reference**            | `string`  | A string that you can use to add any external identifier to the resource. This can be useful for integrating the resource to an external system, like an ERP, a marketing tool, a CRM, or whatever. |
| attributes.**reference\_origin**    | `string`  | Any identifier of the third party system that defines the reference code.                                                                                                                           |
| attributes.**metadata**             | `object`  | Set of key-value pairs that you can attach to the resource. This can be useful for storing additional information about the resource in a structured format.                                        |
| relationships.**event\_stores**     | `array`   | The associated event stores.                                                                                                                                                                        |
| meta.**mode**                       | `string`  | The resource environment (can be one of `test` or `live`)                                                                                                                                           |


# Create an adjustment

How to create an adjustment via API

To [create](https://docs.commercelayer.io/core/creating-resources) a new adjustment, send a `POST` request to the `/api/adjustments` endpoint, passing the resource arguments in the request body.

## Request

**POST** <https://yourdomain.commercelayer.io/api/adjustments>

### Arguments

| Body Parameter                      | Type      | Required                    |
| ----------------------------------- | --------- | --------------------------- |
| **type**                            | `string`  | Required                    |
| attributes.**name**                 | `string`  | Required                    |
| attributes.**currency\_code**       | `string`  | Required                    |
| attributes.**amount\_cents**        | `integer` | Required                    |
| attributes.**distribute\_discount** | `boolean` | Optional, default is 'true' |
| attributes.**reference**            | `string`  | Optional                    |
| attributes.**reference\_origin**    | `string`  | Optional                    |
| attributes.**metadata**             | `object`  | Optional                    |

### Example

{% tabs %}
{% tab title="Request" %}
The following request creates a new adjustment:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/adjustments' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "adjustments",
    "attributes": {
      "name": "Additional service",
      "currency_code": "EUR",
      "amount_cents": 1500
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "adjustments",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/adjustments/XAyRWNUzyN"
    },
    "attributes": {
      "name": "Additional service",
      "currency_code": "EUR",
      "amount_cents": 1500,
      "amount_float": 15.0,
      "formatted_amount": "€15,00",
      "distribute_discount": true,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/adjustments/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/adjustments/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# List all adjustments

How to fetch a collection of adjustments via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a collection of adjustments, send a `GET` request to the `/api/adjustments` endpoint.

## Request

**GET** <https://yourdomain.commercelayer.io/api/adjustments>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches a collection of adjustments:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/adjustments/' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of resource objects:

```json
{
  "data": [
    {
      "id": "XAyRWNUzyN",
      "type": "adjustments",
      "links": {
        "self": "https://yourdomain.commercelayer.io/api/adjustments/XAyRWNUzyN"
      },
      "attributes": {
        "name": "Additional service",
        "currency_code": "EUR",
        "amount_cents": 1500,
        "amount_float": 15.0,
        "formatted_amount": "€15,00",
        "distribute_discount": true,
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": "ANY-EXTERNAL-REFEFERNCE",
        "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
        "metadata": {
          "foo": "bar"
        }
      },
      "relationships": {
        "event_stores": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/adjustments/XAyRWNUzyN/relationships/event_stores",
            "related": "https://yourdomain.commercelayer.io/api/adjustments/XAyRWNUzyN/event_stores"
          }
        }
      },
      "meta": {
        "mode": "test",
        "organization_id": "xRRkjDFafe",
        "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
      }
    },
    {
      "other": "... 9 adjustments (first page)"
    }
  ],
  "meta": {
    "record_count": 140,
    "page_count": 14
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/adjustments?page[number]=1&page[size]=10",
    "next": "https://yourdomain.commercelayer.io/api/adjustments?page[number]=2&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/adjustments?page[number]=14&page[size]=10"
  }
}
```

{% endtab %}
{% endtabs %}

Remember that when you fetch a list of resources you get [paginated](https://docs.commercelayer.io/core/pagination) result.

### Sortable fields

The list of adjustments can be [sorted](https://docs.commercelayer.io/core/sorting-results) by the following fields:

#### Attributes

* `name`
* `currency_code`
* `amount_cents`
* `id`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`

### Filterable fields

The list of adjustments can be [filtered](https://docs.commercelayer.io/core/filtering-data) by the following fields:

#### Attributes

* `name`
* `currency_code`
* `amount_cents`
* `id`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`
* `metadata`


# Retrieve an adjustment

How to fetch a specific adjustment via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a single adjustment, send a `GET` request to the `/api/adjustments/:id` endpoint, where `id` is the ID of the resource that you want to retrieve.

## Request

**GET** <https://yourdomain.commercelayer.io/api/adjustments/:id>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches the adjustment identified by the ID "XAyRWNUzyN":

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/adjustments/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a single resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "adjustments",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/adjustments/XAyRWNUzyN"
    },
    "attributes": {
      "name": "Additional service",
      "currency_code": "EUR",
      "amount_cents": 1500,
      "amount_float": 15.0,
      "formatted_amount": "€15,00",
      "distribute_discount": true,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/adjustments/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/adjustments/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Update an adjustment

How to update an existing adjustment via API

To [update](https://docs.commercelayer.io/core/updating-resources) an existing adjustment, send a `PATCH` request to the `/api/adjustments/:id` endpoint, where `id` is the ID of the resource that you want to update.

Here below the list of all the possible arguments that you can pass with the request body.

## Request

**PATCH** <https://yourdomain.commercelayer.io/api/adjustments/:id>

### Arguments

| Body Parameter                      | Type      | Required |
| ----------------------------------- | --------- | -------- |
| **type**                            | `string`  | Required |
| **id**                              | `string`  | Required |
| attributes.**name**                 | `string`  | Optional |
| attributes.**currency\_code**       | `string`  | Optional |
| attributes.**amount\_cents**        | `integer` | Optional |
| attributes.**distribute\_discount** | `boolean` | Optional |
| attributes.**reference**            | `string`  | Optional |
| attributes.**reference\_origin**    | `string`  | Optional |
| attributes.**metadata**             | `object`  | Optional |

### Example

{% tabs %}
{% tab title="Request" %}
The following request updates the adjustment identified by the ID "XAyRWNUzyN":

```shell
curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/adjustments/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "adjustments",
    "id": "xYZkjABcde",
    "attributes": {
      "reference": "ANY-EXTERNAL-REFEFERNCE"
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the updated resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "adjustments",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/adjustments/XAyRWNUzyN"
    },
    "attributes": {
      "name": "Additional service",
      "currency_code": "EUR",
      "amount_cents": 1500,
      "amount_float": 15.0,
      "formatted_amount": "€15,00",
      "distribute_discount": true,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/adjustments/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/adjustments/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Delete an adjustment

How to delete an existing adjustment via API

To [delete](https://docs.commercelayer.io/core/deleting-resources) an adjustment, send a `DELETE` request to the `/api/adjustments/:id` endpoint, where `id` is the id of the adjustment that you want to delete.

## Request

**DELETE** <https://yourdomain.commercelayer.io/api/adjustments/:id>

### Example

{% tabs %}
{% tab title="Request" %}
The following request tries to delete the adjustment identified by the ID "XAyRWNUzyN":

```shell
curl -g -X DELETE \
  'https://yourdomain.commercelayer.io/api/adjustments/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `204 No Content` status code.
{% endtab %}
{% endtabs %}


# Adyen gateways

The Adyen gateway object and the allowed CRUD operations on the related resource endpoint

Configuring an Adyen payment gateway for a market lets you safely process payments through [Adyen](https://docs.adyen.com/). The Adyen gateway is compliant with the PSD2 European regulation so you can implement a payment flow that supports SCA and 3DS2 by using Adyen's official JS SDK and libraries.

{% hint style="warning" %}
Commerce Layer currently supports the latest version (`v71`) of [Adyen Checkout API](https://docs.adyen.com/api-explorer/Checkout/71/overview) by default and back up to `v66` for backward compatibility. If you're using or have implemented an old integration that requires a version lower than `v71` make sure to specify it in the `api_version` attribute when creating or updating the Adyen gateway resource in Commerce Layer and to use the correct version of Adyen's JS SDK and client libraries as detailed on [Adyen's website](https://docs.adyen.com/online-payments/release-notes).
{% endhint %}

To create an Adyen gateway choose a meaningful name that helps you identify it within your organization and gather all the credentials requested (like [merchant account](https://docs.adyen.com/account/manage-account-structure), [API key](https://docs.adyen.com/development-resources/api-credentials), etc. — contact [Adyen's support](https://www.adyen.help/hc/en-us) if you are not sure about the requested data).

{% hint style="warning" %}
To get real orders and be able to process live transactions with Adyen make sure to get your [live URL prefix](https://docs.adyen.com/development-resources/live-endpoints#live-url-prefix) and correctly set the `live_url_prefix` attribute of the gateway.
{% endhint %}

{% hint style="info" %}
If you're leveraging Adyen's native [Drop-in](https://docs.adyen.com/online-payments/3d-secure/native-3ds2/web-drop-in/) for your integration and want to use the customer payment sources saved from their JS library (highly recommended) instead of the ones [saved in Commerce Layer](/core-api-reference/customer_payment_sources), you can set the `native_customer_payment_sources` attribute to `true` (default is `false`).
{% endhint %}

#### Adyen's notification system

Adyen's notifications are webhooks informing you of payment status updates and newly available reports. Notifications are the only way you'll receive automatic updates about requests that are processed *asynchronously*.

To enable Adyen's notification, first properly set up their configuration on Adyen's customer area (you'll need your `webhook_endpoint_url`) and generate the `webhook_endpoint_secret`. Then use the `async_api` attribute as explained [here](/how-tos/placing-orders/payments/adyen/configuring-the-notification-webhooks).

<details>

<summary>How-to</summary>

Check the related [guide](https://docs.commercelayer.io/developers/v/how-tos/payments/adyen) to learn more on how Commerce Layer handles the server-side part of the integration process with Adyen.

</details>


# The adyen gateway object

A comprehensive list of the adyen gateway resource's attributes and relationships

An adyen gateway object is returned as part of the response body of each successful list, retrieve, create or update API call to the `/api/adyen_gateways` endpoint.

## Fields

| Field                                             | Type      | Description                                                                                                                                                                                         |
| ------------------------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **type**                                          | `string`  | `adyen_gateways`                                                                                                                                                                                    |
| **id**                                            | `string`  | The adyen gateway unique identifier                                                                                                                                                                 |
| links.**self**                                    | `string`  | The adyen gateway endpoint URL                                                                                                                                                                      |
| attributes.**name**                               | `string`  | The payment gateway's internal name.                                                                                                                                                                |
| attributes.**force\_payments**                    | `boolean` | Indicates if the payment source is forced on the editable order upon receiving a successful event from the gateway.                                                                                 |
| attributes.**credential\_keys**                   | `object`  | The payment gateway's API credential keys last digits.                                                                                                                                              |
| attributes.**\_disable**                          | `boolean` | Send this attribute if you want to mark this resource as disabled.                                                                                                                                  |
| attributes.**\_enable**                           | `boolean` | Send this attribute if you want to mark this resource as enabled.                                                                                                                                   |
| attributes.**disabled\_at**                       | `string`  | Time at which this resource was disabled.                                                                                                                                                           |
| attributes.**created\_at**                        | `string`  | Time at which the resource was created.                                                                                                                                                             |
| attributes.**updated\_at**                        | `string`  | Time at which the resource was last updated.                                                                                                                                                        |
| attributes.**reference**                          | `string`  | A string that you can use to add any external identifier to the resource. This can be useful for integrating the resource to an external system, like an ERP, a marketing tool, a CRM, or whatever. |
| attributes.**reference\_origin**                  | `string`  | Any identifier of the third party system that defines the reference code.                                                                                                                           |
| attributes.**metadata**                           | `object`  | Set of key-value pairs that you can attach to the resource. This can be useful for storing additional information about the resource in a structured format.                                        |
| attributes.**\_check**                            | `boolean` | Send this attribute if you want to check the credentials against the payment gateway's APIs.                                                                                                        |
| attributes.**merchant\_account**                  | `string`  | The gateway merchant account.                                                                                                                                                                       |
| attributes.**api\_key**                           | `string`  | The gateway API key.                                                                                                                                                                                |
| attributes.**public\_key**                        | `string`  | The public key linked to your API credential.                                                                                                                                                       |
| attributes.**live\_url\_prefix**                  | `string`  | The prefix of the endpoint used for live transactions.                                                                                                                                              |
| attributes.**api\_version**                       | `integer` | The checkout API version, supported range is from 66 to 71, default is 71.                                                                                                                          |
| attributes.**async\_api**                         | `boolean` | Indicates if the gateway will leverage on the Adyen notification webhooks, using latest API version.                                                                                                |
| attributes.**partial\_payments**                  | `boolean` | Send this attribute if you want to enable partial payments for the order.                                                                                                                           |
| attributes.**order\_expiration\_mins**            | `integer` | The minutes after which the order created for partial payments automatically expires.                                                                                                               |
| attributes.**native\_customer\_payment\_sources** | `boolean` | Indicates if the gateway will use the native customer payment sources.                                                                                                                              |
| attributes.**webhook\_endpoint\_secret**          | `string`  | The gateway webhook endpoint secret, generated by Adyen customer area.                                                                                                                              |
| attributes.**webhook\_endpoint\_url**             | `string`  | The gateway webhook URL, generated automatically.                                                                                                                                                   |
| relationships.**payment\_methods**                | `array`   | The associated payment methods.                                                                                                                                                                     |
| relationships.**event\_stores**                   | `array`   | The associated event stores.                                                                                                                                                                        |
| relationships.**adyen\_payments**                 | `array`   | The associated payments.                                                                                                                                                                            |
| meta.**mode**                                     | `string`  | The resource environment (can be one of `test` or `live`)                                                                                                                                           |


# Create an adyen gateway

How to create an adyen gateway via API

To [create](https://docs.commercelayer.io/core/creating-resources) a new adyen gateway, send a `POST` request to the `/api/adyen_gateways` endpoint, passing the resource arguments in the request body.

## Request

**POST** <https://yourdomain.commercelayer.io/api/adyen\\_gateways>

### Arguments

| Body Parameter                                    | Type      | Required                                    |
| ------------------------------------------------- | --------- | ------------------------------------------- |
| **type**                                          | `string`  | Required                                    |
| attributes.**name**                               | `string`  | Required                                    |
| attributes.**force\_payments**                    | `boolean` | Optional, default is 'false'                |
| attributes.**\_disable**                          | `boolean` | Optional                                    |
| attributes.**\_enable**                           | `boolean` | Optional                                    |
| attributes.**reference**                          | `string`  | Optional                                    |
| attributes.**reference\_origin**                  | `string`  | Optional                                    |
| attributes.**metadata**                           | `object`  | Optional                                    |
| attributes.**\_check**                            | `boolean` | Optional                                    |
| attributes.**merchant\_account**                  | `string`  | Required                                    |
| attributes.**api\_key**                           | `string`  | Required                                    |
| attributes.**public\_key**                        | `string`  | Optional                                    |
| attributes.**live\_url\_prefix**                  | `string`  | Required                                    |
| attributes.**api\_version**                       | `integer` | Optional, default is '71'                   |
| attributes.**async\_api**                         | `boolean` | Optional, default is 'false'                |
| attributes.**partial\_payments**                  | `boolean` | Optional, default is 'false'                |
| attributes.**order\_expiration\_mins**            | `integer` | Optional, default is one day (1440 minutes) |
| attributes.**native\_customer\_payment\_sources** | `boolean` | Optional, default is 'false'                |
| attributes.**webhook\_endpoint\_secret**          | `string`  | Required, if async\_api is truthy           |
| relationships.**adyen\_payments**                 | `array`   | Optional                                    |

### Example

{% tabs %}
{% tab title="Request" %}
The following request creates a new adyen gateway:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/adyen_gateways' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "adyen_gateways",
    "attributes": {
      "name": "US payment gateway",
      "merchant_account": "xxxx-yyyy-zzzz",
      "api_key": "xxxx-yyyy-zzzz",
      "live_url_prefix": "1797a841fbb37ca7-AdyenDemo",
      "webhook_endpoint_secret": "xxxx-yyyy-zzzz"
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "adyen_gateways",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN"
    },
    "attributes": {
      "name": "US payment gateway",
      "force_payments": true,
      "credential_keys": {
        "api_key": "********BW989"
      },
      "disabled_at": "2018-01-01T12:00:00.000Z",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      },
      "live_url_prefix": "1797a841fbb37ca7-AdyenDemo",
      "api_version": 71,
      "async_api": true,
      "partial_payments": false,
      "order_expiration_mins": 30,
      "native_customer_payment_sources": true,
      "webhook_endpoint_secret": "xxxx-yyyy-zzzz",
      "webhook_endpoint_url": "https://core.commercelayer.co/webhook_callbacks/adyen_gateways/xxxxx"
    },
    "relationships": {
      "payment_methods": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/relationships/payment_methods",
          "related": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/payment_methods"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/event_stores"
        }
      },
      "adyen_payments": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/relationships/adyen_payments",
          "related": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/adyen_payments"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# List all adyen gateways

How to fetch a collection of adyen gateways via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a collection of adyen gateways, send a `GET` request to the `/api/adyen_gateways` endpoint.

## Request

**GET** <https://yourdomain.commercelayer.io/api/adyen\\_gateways>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches a collection of adyen gateways:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/adyen_gateways/' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of resource objects:

```json
{
  "data": [
    {
      "id": "XAyRWNUzyN",
      "type": "adyen_gateways",
      "links": {
        "self": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN"
      },
      "attributes": {
        "name": "US payment gateway",
        "force_payments": true,
        "credential_keys": {
          "api_key": "********BW989"
        },
        "disabled_at": "2018-01-01T12:00:00.000Z",
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": "ANY-EXTERNAL-REFEFERNCE",
        "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
        "metadata": {
          "foo": "bar"
        },
        "live_url_prefix": "1797a841fbb37ca7-AdyenDemo",
        "api_version": 71,
        "async_api": true,
        "partial_payments": false,
        "order_expiration_mins": 30,
        "native_customer_payment_sources": true,
        "webhook_endpoint_secret": "xxxx-yyyy-zzzz",
        "webhook_endpoint_url": "https://core.commercelayer.co/webhook_callbacks/adyen_gateways/xxxxx"
      },
      "relationships": {
        "payment_methods": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/relationships/payment_methods",
            "related": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/payment_methods"
          }
        },
        "event_stores": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/relationships/event_stores",
            "related": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/event_stores"
          }
        },
        "adyen_payments": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/relationships/adyen_payments",
            "related": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/adyen_payments"
          }
        }
      },
      "meta": {
        "mode": "test",
        "organization_id": "xRRkjDFafe",
        "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
      }
    },
    {
      "other": "... 9 adyen_gateways (first page)"
    }
  ],
  "meta": {
    "record_count": 140,
    "page_count": 14
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/adyen_gateways?page[number]=1&page[size]=10",
    "next": "https://yourdomain.commercelayer.io/api/adyen_gateways?page[number]=2&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/adyen_gateways?page[number]=14&page[size]=10"
  }
}
```

{% endtab %}
{% endtabs %}

Remember that when you fetch a list of resources you get [paginated](https://docs.commercelayer.io/core/pagination) result.

### Sortable fields

The list of adyen gateways can be [sorted](https://docs.commercelayer.io/core/sorting-results) by the following fields:

#### Attributes

* `name`
* `id`
* `disabled_at`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`
* `merchant_account`

### Filterable fields

The list of adyen gateways can be [filtered](https://docs.commercelayer.io/core/filtering-data) by the following fields:

#### Attributes

* `name`
* `id`
* `disabled_at`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`
* `metadata`

#### Relationships

* `payment_methods`
* `adyen_payments`


# Retrieve an adyen gateway

How to fetch a specific adyen gateway via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a single adyen gateway, send a `GET` request to the `/api/adyen_gateways/:id` endpoint, where `id` is the ID of the resource that you want to retrieve.

## Request

**GET** <https://yourdomain.commercelayer.io/api/adyen\\_gateways/:id>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches the adyen gateway identified by the ID "XAyRWNUzyN":

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a single resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "adyen_gateways",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN"
    },
    "attributes": {
      "name": "US payment gateway",
      "force_payments": true,
      "credential_keys": {
        "api_key": "********BW989"
      },
      "disabled_at": "2018-01-01T12:00:00.000Z",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      },
      "live_url_prefix": "1797a841fbb37ca7-AdyenDemo",
      "api_version": 71,
      "async_api": true,
      "partial_payments": false,
      "order_expiration_mins": 30,
      "native_customer_payment_sources": true,
      "webhook_endpoint_secret": "xxxx-yyyy-zzzz",
      "webhook_endpoint_url": "https://core.commercelayer.co/webhook_callbacks/adyen_gateways/xxxxx"
    },
    "relationships": {
      "payment_methods": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/relationships/payment_methods",
          "related": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/payment_methods"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/event_stores"
        }
      },
      "adyen_payments": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/relationships/adyen_payments",
          "related": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/adyen_payments"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Update an adyen gateway

How to update an existing adyen gateway via API

To [update](https://docs.commercelayer.io/core/updating-resources) an existing adyen gateway, send a `PATCH` request to the `/api/adyen_gateways/:id` endpoint, where `id` is the ID of the resource that you want to update.

Here below the list of all the possible arguments that you can pass with the request body.

## Request

**PATCH** <https://yourdomain.commercelayer.io/api/adyen\\_gateways/:id>

### Arguments

| Body Parameter                                    | Type      | Required |
| ------------------------------------------------- | --------- | -------- |
| **type**                                          | `string`  | Required |
| **id**                                            | `string`  | Required |
| attributes.**name**                               | `string`  | Optional |
| attributes.**force\_payments**                    | `boolean` | Optional |
| attributes.**\_disable**                          | `boolean` | Optional |
| attributes.**\_enable**                           | `boolean` | Optional |
| attributes.**reference**                          | `string`  | Optional |
| attributes.**reference\_origin**                  | `string`  | Optional |
| attributes.**metadata**                           | `object`  | Optional |
| attributes.**\_check**                            | `boolean` | Optional |
| attributes.**merchant\_account**                  | `string`  | Optional |
| attributes.**api\_key**                           | `string`  | Optional |
| attributes.**public\_key**                        | `string`  | Optional |
| attributes.**live\_url\_prefix**                  | `string`  | Optional |
| attributes.**api\_version**                       | `integer` | Optional |
| attributes.**async\_api**                         | `boolean` | Optional |
| attributes.**partial\_payments**                  | `boolean` | Optional |
| attributes.**order\_expiration\_mins**            | `integer` | Optional |
| attributes.**native\_customer\_payment\_sources** | `boolean` | Optional |
| attributes.**webhook\_endpoint\_secret**          | `string`  | Optional |
| relationships.**adyen\_payments**                 | `array`   | Optional |

### Example

{% tabs %}
{% tab title="Request" %}
The following request updates the adyen gateway identified by the ID "XAyRWNUzyN":

```shell
curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "adyen_gateways",
    "id": "xYZkjABcde",
    "attributes": {
      "_disable": true
    },
    "relationships": {
      "adyen_payments": {
        "data": {
          "type": "adyen_payments",
          "id": "ABCRtyUpBa"
        }
      }
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the updated resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "adyen_gateways",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN"
    },
    "attributes": {
      "name": "US payment gateway",
      "force_payments": true,
      "credential_keys": {
        "api_key": "********BW989"
      },
      "disabled_at": "2018-01-01T12:00:00.000Z",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      },
      "live_url_prefix": "1797a841fbb37ca7-AdyenDemo",
      "api_version": 71,
      "async_api": true,
      "partial_payments": false,
      "order_expiration_mins": 30,
      "native_customer_payment_sources": true,
      "webhook_endpoint_secret": "xxxx-yyyy-zzzz",
      "webhook_endpoint_url": "https://core.commercelayer.co/webhook_callbacks/adyen_gateways/xxxxx"
    },
    "relationships": {
      "payment_methods": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/relationships/payment_methods",
          "related": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/payment_methods"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/event_stores"
        }
      },
      "adyen_payments": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/relationships/adyen_payments",
          "related": "https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN/adyen_payments"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Delete an adyen gateway

How to delete an existing adyen gateway via API

To [delete](https://docs.commercelayer.io/core/deleting-resources) an adyen gateway, send a `DELETE` request to the `/api/adyen_gateways/:id` endpoint, where `id` is the id of the adyen gateway that you want to delete.

## Request

**DELETE** <https://yourdomain.commercelayer.io/api/adyen\\_gateways/:id>

### Example

{% tabs %}
{% tab title="Request" %}
The following request tries to delete the adyen gateway identified by the ID "XAyRWNUzyN":

```shell
curl -g -X DELETE \
  'https://yourdomain.commercelayer.io/api/adyen_gateways/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `204 No Content` status code.
{% endtab %}
{% endtabs %}


# Adyen payments

The Adyen payment object and the allowed CRUD operations on the related resource endpoint

Adyen payments are a type of payment source that lets you process payments through [Adyen gateways](/core-api-reference/adyen_gateways).


# The adyen payment object

A comprehensive list of the adyen payment resource's attributes and relationships

An adyen payment object is returned as part of the response body of each successful list, retrieve, create or update API call to the `/api/adyen_payments` endpoint.

## Fields

| Field                                    | Type      | Description                                                                                                                                                                                         |
| ---------------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **type**                                 | `string`  | `adyen_payments`                                                                                                                                                                                    |
| **id**                                   | `string`  | The adyen payment unique identifier                                                                                                                                                                 |
| links.**self**                           | `string`  | The adyen payment endpoint URL                                                                                                                                                                      |
| attributes.**public\_key**               | `string`  | The public key linked to your API credential.                                                                                                                                                       |
| attributes.**payment\_methods**          | `object`  | The merchant available payment methods for the assoiated order (i.e. country and amount). Required by the Adyen JS SDK.                                                                             |
| attributes.**payment\_request\_data**    | `object`  | The Adyen payment request data, collected by client.                                                                                                                                                |
| attributes.**payment\_request\_details** | `object`  | The Adyen additional details request data, collected by client.                                                                                                                                     |
| attributes.**payment\_response**         | `object`  | The Adyen payment response, used by client (includes 'resultCode' and 'action').                                                                                                                    |
| attributes.**mismatched\_amounts**       | `boolean` | Indicates if the order current amount differs form the one of the associated authorization.                                                                                                         |
| attributes.**balance**                   | `integer` | The balance remaining on a shopper's gift card, must be computed by using its related trigger attribute.                                                                                            |
| attributes.**\_authorize**               | `boolean` | Send this attribute if you want to authorize the payment.                                                                                                                                           |
| attributes.**\_details**                 | `boolean` | Send this attribute if you want to send additional details the payment request.                                                                                                                     |
| attributes.**\_balance**                 | `boolean` | Send this attribute if you want retrieve the balance remaining on a shopper's gift card.                                                                                                            |
| attributes.**expires\_at**               | `string`  | The expiration date/time of this Adyen payment (valid for partial payments only).                                                                                                                   |
| attributes.**payment\_instrument**       | `object`  | Information about the payment instrument used in the transaction.                                                                                                                                   |
| attributes.**created\_at**               | `string`  | Time at which the resource was created.                                                                                                                                                             |
| attributes.**updated\_at**               | `string`  | Time at which the resource was last updated.                                                                                                                                                        |
| attributes.**reference**                 | `string`  | A string that you can use to add any external identifier to the resource. This can be useful for integrating the resource to an external system, like an ERP, a marketing tool, a CRM, or whatever. |
| attributes.**reference\_origin**         | `string`  | Any identifier of the third party system that defines the reference code.                                                                                                                           |
| attributes.**metadata**                  | `object`  | Set of key-value pairs that you can attach to the resource. This can be useful for storing additional information about the resource in a structured format.                                        |
| relationships.**order**                  | `object`  | The order associated to the Adyen payment, that is set as its payment source.                                                                                                                       |
| relationships.**payment\_gateway**       | `object`  | The associated payment gateway, inherited by the order payment\_method.                                                                                                                             |
| relationships.**event\_stores**          | `array`   | The associated event stores.                                                                                                                                                                        |
| meta.**mode**                            | `string`  | The resource environment (can be one of `test` or `live`)                                                                                                                                           |


# Create an adyen payment

How to create an adyen payment via API

To [create](https://docs.commercelayer.io/core/creating-resources) a new adyen payment, send a `POST` request to the `/api/adyen_payments` endpoint, passing the resource arguments in the request body.

## Request

**POST** <https://yourdomain.commercelayer.io/api/adyen\\_payments>

### Arguments

| Body Parameter                   | Type     | Required |
| -------------------------------- | -------- | -------- |
| **type**                         | `string` | Required |
| attributes.**reference**         | `string` | Optional |
| attributes.**reference\_origin** | `string` | Optional |
| attributes.**metadata**          | `object` | Optional |
| relationships.**order**          | `object` | Required |

### Example

{% tabs %}
{% tab title="Request" %}
The following request creates a new adyen payment:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/adyen_payments' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "adyen_payments",
    "relationships": {
      "order": {
        "data": {
          "type": "orders",
          "id": "ABCRtyUpBa"
        }
      }
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "adyen_payments",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN"
    },
    "attributes": {
      "public_key": "xxxx-yyyy-zzzz",
      "payment_methods": {
        "foo": "bar"
      },
      "payment_request_data": {
        "foo": "bar"
      },
      "payment_request_details": {
        "foo": "bar"
      },
      "payment_response": {
        "foo": "bar"
      },
      "mismatched_amounts": false,
      "balance": 1000,
      "expires_at": "2018-01-02T12:00:00.000Z",
      "payment_instrument": {
        "issuer": "cl bank",
        "card_type": "visa"
      },
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "order": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/relationships/order",
          "related": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/order"
        }
      },
      "payment_gateway": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/relationships/payment_gateway",
          "related": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/payment_gateway"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# List all adyen payments

How to fetch a collection of adyen payments via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a collection of adyen payments, send a `GET` request to the `/api/adyen_payments` endpoint.

## Request

**GET** <https://yourdomain.commercelayer.io/api/adyen\\_payments>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches a collection of adyen payments:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/adyen_payments/' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of resource objects:

```json
{
  "data": [
    {
      "id": "XAyRWNUzyN",
      "type": "adyen_payments",
      "links": {
        "self": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN"
      },
      "attributes": {
        "public_key": "xxxx-yyyy-zzzz",
        "payment_methods": {
          "foo": "bar"
        },
        "payment_request_data": {
          "foo": "bar"
        },
        "payment_request_details": {
          "foo": "bar"
        },
        "payment_response": {
          "foo": "bar"
        },
        "mismatched_amounts": false,
        "balance": 1000,
        "expires_at": "2018-01-02T12:00:00.000Z",
        "payment_instrument": {
          "issuer": "cl bank",
          "card_type": "visa"
        },
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": "ANY-EXTERNAL-REFEFERNCE",
        "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
        "metadata": {
          "foo": "bar"
        }
      },
      "relationships": {
        "order": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/relationships/order",
            "related": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/order"
          }
        },
        "payment_gateway": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/relationships/payment_gateway",
            "related": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/payment_gateway"
          }
        },
        "event_stores": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/relationships/event_stores",
            "related": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/event_stores"
          }
        }
      },
      "meta": {
        "mode": "test",
        "organization_id": "xRRkjDFafe",
        "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
      }
    },
    {
      "other": "... 9 adyen_payments (first page)"
    }
  ],
  "meta": {
    "record_count": 140,
    "page_count": 14
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/adyen_payments?page[number]=1&page[size]=10",
    "next": "https://yourdomain.commercelayer.io/api/adyen_payments?page[number]=2&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/adyen_payments?page[number]=14&page[size]=10"
  }
}
```

{% endtab %}
{% endtabs %}

Remember that when you fetch a list of resources you get [paginated](https://docs.commercelayer.io/core/pagination) result.

### Sortable fields

The list of adyen payments can be [sorted](https://docs.commercelayer.io/core/sorting-results) by the following fields:

#### Attributes

* `id`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`

#### Relationships

* `order`

### Filterable fields

The list of adyen payments can be [filtered](https://docs.commercelayer.io/core/filtering-data) by the following fields:

#### Attributes

* `id`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`
* `metadata`

#### Relationships

* `order`


# Retrieve an adyen payment

How to fetch a specific adyen payment via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a single adyen payment, send a `GET` request to the `/api/adyen_payments/:id` endpoint, where `id` is the ID of the resource that you want to retrieve.

## Request

**GET** <https://yourdomain.commercelayer.io/api/adyen\\_payments/:id>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches the adyen payment identified by the ID "XAyRWNUzyN":

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a single resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "adyen_payments",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN"
    },
    "attributes": {
      "public_key": "xxxx-yyyy-zzzz",
      "payment_methods": {
        "foo": "bar"
      },
      "payment_request_data": {
        "foo": "bar"
      },
      "payment_request_details": {
        "foo": "bar"
      },
      "payment_response": {
        "foo": "bar"
      },
      "mismatched_amounts": false,
      "balance": 1000,
      "expires_at": "2018-01-02T12:00:00.000Z",
      "payment_instrument": {
        "issuer": "cl bank",
        "card_type": "visa"
      },
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "order": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/relationships/order",
          "related": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/order"
        }
      },
      "payment_gateway": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/relationships/payment_gateway",
          "related": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/payment_gateway"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Update an adyen payment

How to update an existing adyen payment via API

To [update](https://docs.commercelayer.io/core/updating-resources) an existing adyen payment, send a `PATCH` request to the `/api/adyen_payments/:id` endpoint, where `id` is the ID of the resource that you want to update.

Here below the list of all the possible arguments that you can pass with the request body.

## Request

**PATCH** <https://yourdomain.commercelayer.io/api/adyen\\_payments/:id>

### Arguments

| Body Parameter                           | Type      | Required |
| ---------------------------------------- | --------- | -------- |
| **type**                                 | `string`  | Required |
| **id**                                   | `string`  | Required |
| attributes.**payment\_request\_data**    | `object`  | Optional |
| attributes.**payment\_request\_details** | `object`  | Optional |
| attributes.**\_authorize**               | `boolean` | Optional |
| attributes.**\_details**                 | `boolean` | Optional |
| attributes.**\_balance**                 | `boolean` | Optional |
| attributes.**reference**                 | `string`  | Optional |
| attributes.**reference\_origin**         | `string`  | Optional |
| attributes.**metadata**                  | `object`  | Optional |
| relationships.**order**                  | `object`  | Optional |

### Example

{% tabs %}
{% tab title="Request" %}
The following request updates the adyen payment identified by the ID "XAyRWNUzyN":

```shell
curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "adyen_payments",
    "id": "xYZkjABcde",
    "attributes": {
      "payment_request_data": {
        "foo": "bar"
      }
    },
    "relationships": {
      "order": {
        "data": {
          "type": "orders",
          "id": "ABCRtyUpBa"
        }
      }
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the updated resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "adyen_payments",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN"
    },
    "attributes": {
      "public_key": "xxxx-yyyy-zzzz",
      "payment_methods": {
        "foo": "bar"
      },
      "payment_request_data": {
        "foo": "bar"
      },
      "payment_request_details": {
        "foo": "bar"
      },
      "payment_response": {
        "foo": "bar"
      },
      "mismatched_amounts": false,
      "balance": 1000,
      "expires_at": "2018-01-02T12:00:00.000Z",
      "payment_instrument": {
        "issuer": "cl bank",
        "card_type": "visa"
      },
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "order": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/relationships/order",
          "related": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/order"
        }
      },
      "payment_gateway": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/relationships/payment_gateway",
          "related": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/payment_gateway"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Delete an adyen payment

How to delete an existing adyen payment via API

To [delete](https://docs.commercelayer.io/core/deleting-resources) an adyen payment, send a `DELETE` request to the `/api/adyen_payments/:id` endpoint, where `id` is the id of the adyen payment that you want to delete.

## Request

**DELETE** <https://yourdomain.commercelayer.io/api/adyen\\_payments/:id>

### Example

{% tabs %}
{% tab title="Request" %}
The following request tries to delete the adyen payment identified by the ID "XAyRWNUzyN":

```shell
curl -g -X DELETE \
  'https://yourdomain.commercelayer.io/api/adyen_payments/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `204 No Content` status code.
{% endtab %}
{% endtabs %}


# Applications

The application object and the allowed CRUD operations on the related resource endpoint

OAuth applications let you consume the API and build your integrations. Three different types of [API credentials](/core/api-credentials) — providing different types of API credentials — are currently available: **sales channel**, **integration**, and **webapp**.

{% hint style="success" %}
To fully manage your applications and API credentials please leverage the [dedicated endpoint](/provisioning/api-reference/api_credentials) on the Provisioning API.
{% endhint %}

<details>

<summary>How-to</summary>

Check the related [section](/core/api-credentials) to learn more about the available API credetials types, how they work, and which one to choose based on your use case.

</details>

{% hint style="info" %}
This is a **singleton API**, meaning that only the API credentials within the current scope are retrieved. No need to specify the resource ID. If you need to manage (programmatically or manually) all your API credentials you can leverage our [Provisioning API](/provisioning/api-reference/api_credentials). This endpoint is also **immutable**, meaning that create, update, and delete operations are not allowed.
{% endhint %}


# The application object

A comprehensive list of the application resource's attributes and relationships

The application object is returned as part of the response body of each successful retrieve API call to the `/api/application` endpoint.

## Fields

| Field                            | Type      | Description                                                                                                                                                                                         |
| -------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **type**                         | `string`  | `applications`                                                                                                                                                                                      |
| **id**                           | `string`  | The application unique identifier                                                                                                                                                                   |
| links.**self**                   | `string`  | The application endpoint URL                                                                                                                                                                        |
| attributes.**name**              | `string`  | The application's internal name.                                                                                                                                                                    |
| attributes.**kind**              | `string`  | The application's kind. One of 'sales\_channel', 'integration', or 'webapp'.                                                                                                                        |
| attributes.**public\_access**    | `boolean` | Indicates if the application has public access.                                                                                                                                                     |
| attributes.**redirect\_uri**     | `string`  | The application's redirect URI.                                                                                                                                                                     |
| attributes.**scopes**            | `string`  | The application's scopes.                                                                                                                                                                           |
| attributes.**created\_at**       | `string`  | Time at which the resource was created.                                                                                                                                                             |
| attributes.**updated\_at**       | `string`  | Time at which the resource was last updated.                                                                                                                                                        |
| attributes.**reference**         | `string`  | A string that you can use to add any external identifier to the resource. This can be useful for integrating the resource to an external system, like an ERP, a marketing tool, a CRM, or whatever. |
| attributes.**reference\_origin** | `string`  | Any identifier of the third party system that defines the reference code.                                                                                                                           |
| attributes.**metadata**          | `object`  | Set of key-value pairs that you can attach to the resource. This can be useful for storing additional information about the resource in a structured format.                                        |
| meta.**mode**                    | `string`  | The resource environment (can be one of `test` or `live`)                                                                                                                                           |


# Retrieve the application

How to fetch the application via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) the application, send a `GET` request to the `/api/application` endpoint.

## Request

**GET** <https://yourdomain.commercelayer.io/api/application>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches the application in scope:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/application/' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a single resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "applications",
    "attributes": {
      "name": "My app",
      "kind": "sales-channel",
      "public_access": true,
      "redirect_uri": "https://bluebrand.com/img/logo.svg",
      "scopes": "market:all market:9 market:122 market:6 stock_location:6 stock_location:33",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Attachments

The attachment object and the allowed CRUD operations on the related resource endpoint

Attachments can be associated with any resource as a reference to any external document, through the `url` attribute.


# The attachment object

A comprehensive list of the attachment resource's attributes and relationships

An attachment object is returned as part of the response body of each successful list, retrieve, create or update API call to the `/api/attachments` endpoint.

## Fields

| Field                            | Type     | Description                                                                                                                                                                                         |
| -------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **type**                         | `string` | `attachments`                                                                                                                                                                                       |
| **id**                           | `string` | The attachment unique identifier                                                                                                                                                                    |
| links.**self**                   | `string` | The attachment endpoint URL                                                                                                                                                                         |
| attributes.**name**              | `string` | The internal name of the attachment.                                                                                                                                                                |
| attributes.**description**       | `string` | An internal description of the attachment.                                                                                                                                                          |
| attributes.**url**               | `string` | The attachment URL.                                                                                                                                                                                 |
| attributes.**created\_at**       | `string` | Time at which the resource was created.                                                                                                                                                             |
| attributes.**updated\_at**       | `string` | Time at which the resource was last updated.                                                                                                                                                        |
| attributes.**reference**         | `string` | A string that you can use to add any external identifier to the resource. This can be useful for integrating the resource to an external system, like an ERP, a marketing tool, a CRM, or whatever. |
| attributes.**reference\_origin** | `string` | Any identifier of the third party system that defines the reference code.                                                                                                                           |
| attributes.**metadata**          | `object` | Set of key-value pairs that you can attach to the resource. This can be useful for storing additional information about the resource in a structured format.                                        |
| relationships.**attachable**     | `object` | The resource the attachment belongs to.                                                                                                                                                             |
| relationships.**event\_stores**  | `array`  | The associated event stores.                                                                                                                                                                        |
| meta.**mode**                    | `string` | The resource environment (can be one of `test` or `live`)                                                                                                                                           |


# Create an attachment

How to create an attachment via API

To [create](https://docs.commercelayer.io/core/creating-resources) a new attachment, send a `POST` request to the `/api/attachments` endpoint, passing the resource arguments in the request body.

## Request

**POST** <https://yourdomain.commercelayer.io/api/attachments>

### Arguments

| Body Parameter                   | Type     | Required |
| -------------------------------- | -------- | -------- |
| **type**                         | `string` | Required |
| attributes.**name**              | `string` | Required |
| attributes.**description**       | `string` | Optional |
| attributes.**url**               | `string` | Optional |
| attributes.**reference**         | `string` | Optional |
| attributes.**reference\_origin** | `string` | Optional |
| attributes.**metadata**          | `object` | Optional |
| relationships.**attachable**     | `object` | Required |

### Example

{% tabs %}
{% tab title="Request" %}
The following request creates a new attachment:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/attachments' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "attachments",
    "attributes": {
      "name": "DDT transport document"
    },
    "relationships": {
      "attachable": {
        "data": {
          "type": "shipping_zones",
          "id": "ABCRtyUpBa"
        }
      }
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "attachments",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/attachments/XAyRWNUzyN"
    },
    "attributes": {
      "name": "DDT transport document",
      "description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
      "url": "https://s3.yourdomain.com/attachment.pdf",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "attachable": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/attachments/XAyRWNUzyN/relationships/attachable",
          "related": "https://yourdomain.commercelayer.io/api/attachments/XAyRWNUzyN/attachable"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/attachments/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/attachments/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# List all attachments

How to fetch a collection of attachments via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a collection of attachments, send a `GET` request to the `/api/attachments` endpoint.

## Request

**GET** <https://yourdomain.commercelayer.io/api/attachments>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches a collection of attachments:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/attachments/' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of resource objects:

```json
{
  "data": [
    {
      "id": "XAyRWNUzyN",
      "type": "attachments",
      "links": {
        "self": "https://yourdomain.commercelayer.io/api/attachments/XAyRWNUzyN"
      },
      "attributes": {
        "name": "DDT transport document",
        "description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        "url": "https://s3.yourdomain.com/attachment.pdf",
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": "ANY-EXTERNAL-REFEFERNCE",
        "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
        "metadata": {
          "foo": "bar"
        }
      },
      "relationships": {
        "attachable": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/attachments/XAyRWNUzyN/relationships/attachable",
            "related": "https://yourdomain.commercelayer.io/api/attachments/XAyRWNUzyN/attachable"
          }
        },
        "event_stores": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/attachments/XAyRWNUzyN/relationships/event_stores",
            "related": "https://yourdomain.commercelayer.io/api/attachments/XAyRWNUzyN/event_stores"
          }
        }
      },
      "meta": {
        "mode": "test",
        "organization_id": "xRRkjDFafe",
        "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
      }
    },
    {
      "other": "... 9 attachments (first page)"
    }
  ],
  "meta": {
    "record_count": 140,
    "page_count": 14
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/attachments?page[number]=1&page[size]=10",
    "next": "https://yourdomain.commercelayer.io/api/attachments?page[number]=2&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/attachments?page[number]=14&page[size]=10"
  }
}
```

{% endtab %}
{% endtabs %}

Remember that when you fetch a list of resources you get [paginated](https://docs.commercelayer.io/core/pagination) result.

### Sortable fields

The list of attachments can be [sorted](https://docs.commercelayer.io/core/sorting-results) by the following fields:

#### Attributes

* `name`
* `id`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`

### Filterable fields

The list of attachments can be [filtered](https://docs.commercelayer.io/core/filtering-data) by the following fields:

#### Attributes

* `name`
* `description`
* `id`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`
* `metadata`


# Retrieve an attachment

How to fetch a specific attachment via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a single attachment, send a `GET` request to the `/api/attachments/:id` endpoint, where `id` is the ID of the resource that you want to retrieve.

## Request

**GET** <https://yourdomain.commercelayer.io/api/attachments/:id>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches the attachment identified by the ID "XAyRWNUzyN":

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/attachments/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a single resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "attachments",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/attachments/XAyRWNUzyN"
    },
    "attributes": {
      "name": "DDT transport document",
      "description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
      "url": "https://s3.yourdomain.com/attachment.pdf",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "attachable": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/attachments/XAyRWNUzyN/relationships/attachable",
          "related": "https://yourdomain.commercelayer.io/api/attachments/XAyRWNUzyN/attachable"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/attachments/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/attachments/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Update an attachment

How to update an existing attachment via API

To [update](https://docs.commercelayer.io/core/updating-resources) an existing attachment, send a `PATCH` request to the `/api/attachments/:id` endpoint, where `id` is the ID of the resource that you want to update.

Here below the list of all the possible arguments that you can pass with the request body.

## Request

**PATCH** <https://yourdomain.commercelayer.io/api/attachments/:id>

### Arguments

| Body Parameter                   | Type     | Required |
| -------------------------------- | -------- | -------- |
| **type**                         | `string` | Required |
| **id**                           | `string` | Required |
| attributes.**name**              | `string` | Optional |
| attributes.**description**       | `string` | Optional |
| attributes.**url**               | `string` | Optional |
| attributes.**reference**         | `string` | Optional |
| attributes.**reference\_origin** | `string` | Optional |
| attributes.**metadata**          | `object` | Optional |
| relationships.**attachable**     | `object` | Optional |

### Example

{% tabs %}
{% tab title="Request" %}
The following request updates the attachment identified by the ID "XAyRWNUzyN":

```shell
curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/attachments/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "attachments",
    "id": "xYZkjABcde",
    "attributes": {
      "description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
    },
    "relationships": {
      "attachable": {
        "data": {
          "type": "attachables",
          "id": "ABCRtyUpBa"
        }
      }
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the updated resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "attachments",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/attachments/XAyRWNUzyN"
    },
    "attributes": {
      "name": "DDT transport document",
      "description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
      "url": "https://s3.yourdomain.com/attachment.pdf",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "attachable": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/attachments/XAyRWNUzyN/relationships/attachable",
          "related": "https://yourdomain.commercelayer.io/api/attachments/XAyRWNUzyN/attachable"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/attachments/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/attachments/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Delete an attachment

How to delete an existing attachment via API

To [delete](https://docs.commercelayer.io/core/deleting-resources) an attachment, send a `DELETE` request to the `/api/attachments/:id` endpoint, where `id` is the id of the attachment that you want to delete.

## Request

**DELETE** <https://yourdomain.commercelayer.io/api/attachments/:id>

### Example

{% tabs %}
{% tab title="Request" %}
The following request tries to delete the attachment identified by the ID "XAyRWNUzyN":

```shell
curl -g -X DELETE \
  'https://yourdomain.commercelayer.io/api/attachments/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `204 No Content` status code.
{% endtab %}
{% endtabs %}


# Authorizations

The authorization object and the allowed CRUD operations on the related resource endpoint

When an [order](/core-api-reference/orders) is placed a successful authorization transaction is created and the order's payment status becomes `authorized` (except for async payments, i.e. [Stripe](/core-api-reference/stripe_payments))

Fetching an authorization returns all the information and messages provided by the [payment gateway](/core-api-reference/payment_gateways). You can update an authorization to [capture](/core-api-reference/captures) or [void](/core-api-reference/voids) it.

If an authorization gets stuck (for any reason) on our platform but succeeds on the payment gateway, you can [unblock](/core-api-reference/transactions#unblocking-stuck-transactions) it by passing the `_forward` trigger attribute. In this case, the associated order is also placed at the end of the forwarding process, to avoid any possible modifications.

If an authorization associated with a still pending order succeeded and the order is updated (introducing an amount mismatch scenario), you can [reset the transaction](/core-api-reference/transactions#cancelling-transactions) by passing the `_cancel` trigger attribute.

<details>

<summary>Data model</summary>

Check the related [ER diagram](https://commercelayer.io/docs/data-model/orders-management) and explore the flowchart that illustrates how the authorization resource relates to the order and the other transaction APIs.

</details>

{% hint style="info" %}
Create and delete operations are not allowed on this endpoint. You can only fetch a list of authorization or a specific single one, which can also be updated in order to mark it as succeeded, pass specific trigger attributes, or add/change common attributes (metadata, references, etc.).
{% endhint %}


# The authorization object

A comprehensive list of the authorization resource's attributes and relationships

An authorization object is returned as part of the response body of each successful list, retrieve or update API call to the `/api/authorizations` endpoint.

## Fields

| Field                                      | Type      | Description                                                                                                                                                                                         |
| ------------------------------------------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **type**                                   | `string`  | `authorizations`                                                                                                                                                                                    |
| **id**                                     | `string`  | The authorization unique identifier                                                                                                                                                                 |
| links.**self**                             | `string`  | The authorization endpoint URL                                                                                                                                                                      |
| attributes.**number**                      | `string`  | The transaction number, auto generated.                                                                                                                                                             |
| attributes.**payment\_method\_type**       | `string`  | Information about the payment method used in the transaction.                                                                                                                                       |
| attributes.**currency\_code**              | `string`  | The international 3-letter currency code as defined by the ISO 4217 standard, inherited from the associated order.                                                                                  |
| attributes.**amount\_cents**               | `integer` | The transaction amount, in cents.                                                                                                                                                                   |
| attributes.**amount\_float**               | `float`   | The transaction amount, float.                                                                                                                                                                      |
| attributes.**formatted\_amount**           | `string`  | The transaction amount, formatted.                                                                                                                                                                  |
| attributes.**succeeded**                   | `boolean` | Indicates if the transaction is successful.                                                                                                                                                         |
| attributes.**message**                     | `string`  | The message returned by the payment gateway.                                                                                                                                                        |
| attributes.**error\_code**                 | `string`  | The error code, if any, returned by the payment gateway.                                                                                                                                            |
| attributes.**error\_detail**               | `string`  | The error detail, if any, returned by the payment gateway.                                                                                                                                          |
| attributes.**token**                       | `string`  | The token identifying the transaction, returned by the payment gateway.                                                                                                                             |
| attributes.**gateway\_transaction\_id**    | `string`  | The ID identifying the transaction, returned by the payment gateway.                                                                                                                                |
| attributes.**\_forward**                   | `boolean` | Send this attribute if you want to forward a stuck transaction to succeeded and update associated order states accordingly.                                                                         |
| attributes.**created\_at**                 | `string`  | Time at which the resource was created.                                                                                                                                                             |
| attributes.**updated\_at**                 | `string`  | Time at which the resource was last updated.                                                                                                                                                        |
| attributes.**reference**                   | `string`  | A string that you can use to add any external identifier to the resource. This can be useful for integrating the resource to an external system, like an ERP, a marketing tool, a CRM, or whatever. |
| attributes.**reference\_origin**           | `string`  | Any identifier of the third party system that defines the reference code.                                                                                                                           |
| attributes.**metadata**                    | `object`  | Set of key-value pairs that you can attach to the resource. This can be useful for storing additional information about the resource in a structured format.                                        |
| attributes.**cvv\_code**                   | `string`  | The CVV code returned by the payment gateway.                                                                                                                                                       |
| attributes.**cvv\_message**                | `string`  | The CVV message returned by the payment gateway.                                                                                                                                                    |
| attributes.**avs\_code**                   | `string`  | The AVS code returned by the payment gateway.                                                                                                                                                       |
| attributes.**avs\_message**                | `string`  | The AVS message returned by the payment gateway.                                                                                                                                                    |
| attributes.**fraud\_review**               | `string`  | The fraud review message, if any, returned by the payment gateway.                                                                                                                                  |
| attributes.**\_capture**                   | `boolean` | Send this attribute if you want to create a capture for this authorization.                                                                                                                         |
| attributes.**\_capture\_amount\_cents**    | `integer` | Send this attribute as a value in cents if you want to overwrite the amount to be captured.                                                                                                         |
| attributes.**capture\_amount\_cents**      | `integer` | The amount to be captured, in cents.                                                                                                                                                                |
| attributes.**capture\_amount\_float**      | `float`   | The amount to be captured, float.                                                                                                                                                                   |
| attributes.**formatted\_capture\_amount**  | `string`  | The amount to be captured, formatted.                                                                                                                                                               |
| attributes.**capture\_balance\_cents**     | `integer` | The balance to be captured, in cents.                                                                                                                                                               |
| attributes.**capture\_balance\_float**     | `float`   | The balance to be captured, float.                                                                                                                                                                  |
| attributes.**formatted\_capture\_balance** | `string`  | The balance to be captured, formatted.                                                                                                                                                              |
| attributes.**\_void**                      | `boolean` | Send this attribute if you want to create a void for this authorization.                                                                                                                            |
| attributes.**void\_balance\_cents**        | `integer` | The balance to be voided, in cents.                                                                                                                                                                 |
| attributes.**void\_balance\_float**        | `float`   | The balance to be voided, float.                                                                                                                                                                    |
| attributes.**formatted\_void\_balance**    | `string`  | The balance to be voided, formatted.                                                                                                                                                                |
| attributes.**\_cancel**                    | `boolean` | Send this attribute if you want to void a succeeded authorization of a pending order (which is left unpaid).                                                                                        |
| relationships.**order**                    | `object`  | The associated order.                                                                                                                                                                               |
| relationships.**payment\_source**          | `object`  | The associated payment source.                                                                                                                                                                      |
| relationships.**attachments**              | `array`   | The associated attachments.                                                                                                                                                                         |
| relationships.**events**                   | `array`   | The associated events.                                                                                                                                                                              |
| relationships.**event\_stores**            | `array`   | The associated event stores.                                                                                                                                                                        |
| relationships.**captures**                 | `array`   | The associated captures.                                                                                                                                                                            |
| relationships.**voids**                    | `array`   | The associated voids.                                                                                                                                                                               |
| meta.**mode**                              | `string`  | The resource environment (can be one of `test` or `live`)                                                                                                                                           |


# List all authorizations

How to fetch a collection of authorizations via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a collection of authorizations, send a `GET` request to the `/api/authorizations` endpoint.

## Request

**GET** <https://yourdomain.commercelayer.io/api/authorizations>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches a collection of authorizations:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/authorizations/' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of resource objects:

```json
{
  "data": [
    {
      "id": "XAyRWNUzyN",
      "type": "authorizations",
      "links": {
        "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN"
      },
      "attributes": {
        "number": "42/T/001",
        "type": "authorizations",
        "payment_method_type": "credit card",
        "currency_code": "EUR",
        "amount_cents": 1500,
        "amount_float": 15.0,
        "formatted_amount": "€15,00",
        "succeeded": false,
        "message": "Accepted",
        "error_code": "00001",
        "error_detail": "Already settled",
        "token": "xxxx-yyyy-zzzz",
        "gateway_transaction_id": "xxxx-yyyy-zzzz",
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": "ANY-EXTERNAL-REFEFERNCE",
        "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
        "metadata": {
          "foo": "bar"
        },
        "cvv_code": "000",
        "cvv_message": "validated",
        "avs_code": "000",
        "avs_message": "validated",
        "fraud_review": "passed",
        "capture_amount_cents": 500,
        "capture_amount_float": 5.0,
        "formatted_capture_amount": "€5,00",
        "capture_balance_cents": 1000,
        "capture_balance_float": 10.0,
        "formatted_capture_balance": "€10,00",
        "void_balance_cents": 1500,
        "void_balance_float": 15.0,
        "formatted_void_balance": "€15,00"
      },
      "relationships": {
        "order": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/relationships/order",
            "related": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/order"
          }
        },
        "payment_source": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/relationships/payment_source",
            "related": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/payment_source"
          }
        },
        "attachments": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/relationships/attachments",
            "related": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/attachments"
          }
        },
        "events": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/relationships/events",
            "related": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/events"
          }
        },
        "event_stores": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/relationships/event_stores",
            "related": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/event_stores"
          }
        },
        "captures": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/relationships/captures",
            "related": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/captures"
          }
        },
        "voids": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/relationships/voids",
            "related": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/voids"
          }
        }
      },
      "meta": {
        "mode": "test",
        "organization_id": "xRRkjDFafe",
        "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
      }
    },
    {
      "other": "... 9 authorizations (first page)"
    }
  ],
  "meta": {
    "record_count": 140,
    "page_count": 14
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/authorizations?page[number]=1&page[size]=10",
    "next": "https://yourdomain.commercelayer.io/api/authorizations?page[number]=2&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/authorizations?page[number]=14&page[size]=10"
  }
}
```

{% endtab %}
{% endtabs %}

Remember that when you fetch a list of resources you get [paginated](https://docs.commercelayer.io/core/pagination) result.

### Sortable fields

The list of authorizations can be [sorted](https://docs.commercelayer.io/core/sorting-results) by the following fields:

#### Attributes

* `number`
* `type`
* `amount_cents`
* `id`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`

#### Relationships

* `order`

### Filterable fields

The list of authorizations can be [filtered](https://docs.commercelayer.io/core/filtering-data) by the following fields:

#### Attributes

* `number`
* `type`
* `currency_code`
* `amount_cents`
* `succeeded`
* `message`
* `error_code`
* `error_detail`
* `token`
* `gateway_transaction_id`
* `id`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`
* `metadata`

#### Relationships

* `order`
* `payment_source`
* `attachments`
* `events`


# Retrieve an authorization

How to fetch a specific authorization via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a single authorization, send a `GET` request to the `/api/authorizations/:id` endpoint, where `id` is the ID of the resource that you want to retrieve.

## Request

**GET** <https://yourdomain.commercelayer.io/api/authorizations/:id>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches the authorization identified by the ID "XAyRWNUzyN":

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a single resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "authorizations",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN"
    },
    "attributes": {
      "number": "42/T/001",
      "type": "authorizations",
      "payment_method_type": "credit card",
      "currency_code": "EUR",
      "amount_cents": 1500,
      "amount_float": 15.0,
      "formatted_amount": "€15,00",
      "succeeded": false,
      "message": "Accepted",
      "error_code": "00001",
      "error_detail": "Already settled",
      "token": "xxxx-yyyy-zzzz",
      "gateway_transaction_id": "xxxx-yyyy-zzzz",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      },
      "cvv_code": "000",
      "cvv_message": "validated",
      "avs_code": "000",
      "avs_message": "validated",
      "fraud_review": "passed",
      "capture_amount_cents": 500,
      "capture_amount_float": 5.0,
      "formatted_capture_amount": "€5,00",
      "capture_balance_cents": 1000,
      "capture_balance_float": 10.0,
      "formatted_capture_balance": "€10,00",
      "void_balance_cents": 1500,
      "void_balance_float": 15.0,
      "formatted_void_balance": "€15,00"
    },
    "relationships": {
      "order": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/relationships/order",
          "related": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/order"
        }
      },
      "payment_source": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/relationships/payment_source",
          "related": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/payment_source"
        }
      },
      "attachments": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/relationships/attachments",
          "related": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/attachments"
        }
      },
      "events": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/relationships/events",
          "related": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/events"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/event_stores"
        }
      },
      "captures": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/relationships/captures",
          "related": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/captures"
        }
      },
      "voids": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/relationships/voids",
          "related": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/voids"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Update an authorization

How to update an existing authorization via API

To [update](https://docs.commercelayer.io/core/updating-resources) an existing authorization, send a `PATCH` request to the `/api/authorizations/:id` endpoint, where `id` is the ID of the resource that you want to update.

Here below the list of all the possible arguments that you can pass with the request body.

## Request

**PATCH** <https://yourdomain.commercelayer.io/api/authorizations/:id>

### Arguments

| Body Parameter                          | Type      | Required |
| --------------------------------------- | --------- | -------- |
| **type**                                | `string`  | Required |
| **id**                                  | `string`  | Required |
| attributes.**succeeded**                | `boolean` | Optional |
| attributes.**\_forward**                | `boolean` | Optional |
| attributes.**reference**                | `string`  | Optional |
| attributes.**reference\_origin**        | `string`  | Optional |
| attributes.**metadata**                 | `object`  | Optional |
| attributes.**\_capture**                | `boolean` | Optional |
| attributes.**\_capture\_amount\_cents** | `integer` | Optional |
| attributes.**\_void**                   | `boolean` | Optional |
| attributes.**\_cancel**                 | `boolean` | Optional |

### Example

{% tabs %}
{% tab title="Request" %}
The following request updates the authorization identified by the ID "XAyRWNUzyN":

```shell
curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "authorizations",
    "id": "xYZkjABcde",
    "attributes": {
      "_capture": true,
      "_capture_amount_cents": 500
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the updated resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "authorizations",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN"
    },
    "attributes": {
      "number": "42/T/001",
      "type": "authorizations",
      "payment_method_type": "credit card",
      "currency_code": "EUR",
      "amount_cents": 1500,
      "amount_float": 15.0,
      "formatted_amount": "€15,00",
      "succeeded": false,
      "message": "Accepted",
      "error_code": "00001",
      "error_detail": "Already settled",
      "token": "xxxx-yyyy-zzzz",
      "gateway_transaction_id": "xxxx-yyyy-zzzz",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      },
      "cvv_code": "000",
      "cvv_message": "validated",
      "avs_code": "000",
      "avs_message": "validated",
      "fraud_review": "passed",
      "capture_amount_cents": 500,
      "capture_amount_float": 5.0,
      "formatted_capture_amount": "€5,00",
      "capture_balance_cents": 1000,
      "capture_balance_float": 10.0,
      "formatted_capture_balance": "€10,00",
      "void_balance_cents": 1500,
      "void_balance_float": 15.0,
      "formatted_void_balance": "€15,00"
    },
    "relationships": {
      "order": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/relationships/order",
          "related": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/order"
        }
      },
      "payment_source": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/relationships/payment_source",
          "related": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/payment_source"
        }
      },
      "attachments": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/relationships/attachments",
          "related": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/attachments"
        }
      },
      "events": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/relationships/events",
          "related": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/events"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/event_stores"
        }
      },
      "captures": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/relationships/captures",
          "related": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/captures"
        }
      },
      "voids": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/relationships/voids",
          "related": "https://yourdomain.commercelayer.io/api/authorizations/XAyRWNUzyN/voids"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Avalara accounts

The Avalara account object and the allowed CRUD operations on the related resource endpoint

Configure your [Avalara](https://www.avalara.com/us/en/index.html) account to automatically compute tax calculations for the orders of the associated market.


# The avalara account object

A comprehensive list of the avalara account resource's attributes and relationships

An avalara account object is returned as part of the response body of each successful list, retrieve, create or update API call to the `/api/avalara_accounts` endpoint.

## Fields

| Field                             | Type      | Description                                                                                                                                                                                         |
| --------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **type**                          | `string`  | `avalara_accounts`                                                                                                                                                                                  |
| **id**                            | `string`  | The avalara account unique identifier                                                                                                                                                               |
| links.**self**                    | `string`  | The avalara account endpoint URL                                                                                                                                                                    |
| attributes.**name**               | `string`  | The tax calculator's internal name.                                                                                                                                                                 |
| attributes.**created\_at**        | `string`  | Time at which the resource was created.                                                                                                                                                             |
| attributes.**updated\_at**        | `string`  | Time at which the resource was last updated.                                                                                                                                                        |
| attributes.**reference**          | `string`  | A string that you can use to add any external identifier to the resource. This can be useful for integrating the resource to an external system, like an ERP, a marketing tool, a CRM, or whatever. |
| attributes.**reference\_origin**  | `string`  | Any identifier of the third party system that defines the reference code.                                                                                                                           |
| attributes.**metadata**           | `object`  | Set of key-value pairs that you can attach to the resource. This can be useful for storing additional information about the resource in a structured format.                                        |
| attributes.**username**           | `string`  | The Avalara account username.                                                                                                                                                                       |
| attributes.**password**           | `string`  | The Avalara account password.                                                                                                                                                                       |
| attributes.**company\_code**      | `string`  | The Avalara company code.                                                                                                                                                                           |
| attributes.**commit\_invoice**    | `boolean` | Indicates if the transaction will be recorded and visible on the Avalara website.                                                                                                                   |
| attributes.**ddp**                | `boolean` | Indicates if the seller is responsible for paying/remitting the customs duty & import tax to the customs authorities.                                                                               |
| relationships.**markets**         | `array`   | The associated markets.                                                                                                                                                                             |
| relationships.**attachments**     | `array`   | The associated attachments.                                                                                                                                                                         |
| relationships.**events**          | `array`   | The associated events.                                                                                                                                                                              |
| relationships.**event\_stores**   | `array`   | The associated event stores.                                                                                                                                                                        |
| relationships.**tax\_categories** | `array`   | The associated tax categories.                                                                                                                                                                      |
| meta.**mode**                     | `string`  | The resource environment (can be one of `test` or `live`)                                                                                                                                           |


# Create an avalara account

How to create an avalara account via API

To [create](https://docs.commercelayer.io/core/creating-resources) a new avalara account, send a `POST` request to the `/api/avalara_accounts` endpoint, passing the resource arguments in the request body.

## Request

**POST** <https://yourdomain.commercelayer.io/api/avalara\\_accounts>

### Arguments

| Body Parameter                    | Type      | Required |
| --------------------------------- | --------- | -------- |
| **type**                          | `string`  | Required |
| attributes.**name**               | `string`  | Required |
| attributes.**reference**          | `string`  | Optional |
| attributes.**reference\_origin**  | `string`  | Optional |
| attributes.**metadata**           | `object`  | Optional |
| attributes.**username**           | `string`  | Required |
| attributes.**password**           | `string`  | Required |
| attributes.**company\_code**      | `string`  | Required |
| attributes.**commit\_invoice**    | `boolean` | Optional |
| attributes.**ddp**                | `boolean` | Optional |
| relationships.**tax\_categories** | `array`   | Optional |

### Example

{% tabs %}
{% tab title="Request" %}
The following request creates a new avalara account:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/avalara_accounts' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "avalara_accounts",
    "attributes": {
      "name": "Personal tax calculator",
      "username": "user@mydomain.com",
      "password": "secret",
      "company_code": "MYCOMPANY"
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "avalara_accounts",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN"
    },
    "attributes": {
      "name": "Personal tax calculator",
      "type": "avalara_accounts",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      },
      "username": "user@mydomain.com",
      "company_code": "MYCOMPANY",
      "commit_invoice": true,
      "ddp": true
    },
    "relationships": {
      "markets": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/relationships/markets",
          "related": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/markets"
        }
      },
      "attachments": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/relationships/attachments",
          "related": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/attachments"
        }
      },
      "events": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/relationships/events",
          "related": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/events"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/event_stores"
        }
      },
      "tax_categories": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/relationships/tax_categories",
          "related": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/tax_categories"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# List all avalara accounts

How to fetch a collection of avalara accounts via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a collection of avalara accounts, send a `GET` request to the `/api/avalara_accounts` endpoint.

## Request

**GET** <https://yourdomain.commercelayer.io/api/avalara\\_accounts>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches a collection of avalara accounts:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/avalara_accounts/' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of resource objects:

```json
{
  "data": [
    {
      "id": "XAyRWNUzyN",
      "type": "avalara_accounts",
      "links": {
        "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN"
      },
      "attributes": {
        "name": "Personal tax calculator",
        "type": "avalara_accounts",
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": "ANY-EXTERNAL-REFEFERNCE",
        "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
        "metadata": {
          "foo": "bar"
        },
        "username": "user@mydomain.com",
        "company_code": "MYCOMPANY",
        "commit_invoice": true,
        "ddp": true
      },
      "relationships": {
        "markets": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/relationships/markets",
            "related": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/markets"
          }
        },
        "attachments": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/relationships/attachments",
            "related": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/attachments"
          }
        },
        "events": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/relationships/events",
            "related": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/events"
          }
        },
        "event_stores": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/relationships/event_stores",
            "related": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/event_stores"
          }
        },
        "tax_categories": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/relationships/tax_categories",
            "related": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/tax_categories"
          }
        }
      },
      "meta": {
        "mode": "test",
        "organization_id": "xRRkjDFafe",
        "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
      }
    },
    {
      "other": "... 9 avalara_accounts (first page)"
    }
  ],
  "meta": {
    "record_count": 140,
    "page_count": 14
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/avalara_accounts?page[number]=1&page[size]=10",
    "next": "https://yourdomain.commercelayer.io/api/avalara_accounts?page[number]=2&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/avalara_accounts?page[number]=14&page[size]=10"
  }
}
```

{% endtab %}
{% endtabs %}

Remember that when you fetch a list of resources you get [paginated](https://docs.commercelayer.io/core/pagination) result.

### Sortable fields

The list of avalara accounts can be [sorted](https://docs.commercelayer.io/core/sorting-results) by the following fields:

#### Attributes

* `name`
* `type`
* `id`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`

### Filterable fields

The list of avalara accounts can be [filtered](https://docs.commercelayer.io/core/filtering-data) by the following fields:

#### Attributes

* `name`
* `type`
* `id`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`
* `metadata`

#### Relationships

* `attachments`
* `events`
* `tax_categories`


# Retrieve an avalara account

How to fetch a specific avalara account via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a single avalara account, send a `GET` request to the `/api/avalara_accounts/:id` endpoint, where `id` is the ID of the resource that you want to retrieve.

## Request

**GET** <https://yourdomain.commercelayer.io/api/avalara\\_accounts/:id>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches the avalara account identified by the ID "XAyRWNUzyN":

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a single resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "avalara_accounts",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN"
    },
    "attributes": {
      "name": "Personal tax calculator",
      "type": "avalara_accounts",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      },
      "username": "user@mydomain.com",
      "company_code": "MYCOMPANY",
      "commit_invoice": true,
      "ddp": true
    },
    "relationships": {
      "markets": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/relationships/markets",
          "related": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/markets"
        }
      },
      "attachments": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/relationships/attachments",
          "related": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/attachments"
        }
      },
      "events": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/relationships/events",
          "related": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/events"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/event_stores"
        }
      },
      "tax_categories": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/relationships/tax_categories",
          "related": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/tax_categories"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Update an avalara account

How to update an existing avalara account via API

To [update](https://docs.commercelayer.io/core/updating-resources) an existing avalara account, send a `PATCH` request to the `/api/avalara_accounts/:id` endpoint, where `id` is the ID of the resource that you want to update.

Here below the list of all the possible arguments that you can pass with the request body.

## Request

**PATCH** <https://yourdomain.commercelayer.io/api/avalara\\_accounts/:id>

### Arguments

| Body Parameter                    | Type      | Required |
| --------------------------------- | --------- | -------- |
| **type**                          | `string`  | Required |
| **id**                            | `string`  | Required |
| attributes.**name**               | `string`  | Optional |
| attributes.**reference**          | `string`  | Optional |
| attributes.**reference\_origin**  | `string`  | Optional |
| attributes.**metadata**           | `object`  | Optional |
| attributes.**username**           | `string`  | Optional |
| attributes.**password**           | `string`  | Optional |
| attributes.**company\_code**      | `string`  | Optional |
| attributes.**commit\_invoice**    | `boolean` | Optional |
| attributes.**ddp**                | `boolean` | Optional |
| relationships.**tax\_categories** | `array`   | Optional |

### Example

{% tabs %}
{% tab title="Request" %}
The following request updates the avalara account identified by the ID "XAyRWNUzyN":

```shell
curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "avalara_accounts",
    "id": "xYZkjABcde",
    "attributes": {
      "reference": "ANY-EXTERNAL-REFEFERNCE"
    },
    "relationships": {
      "tax_categories": {
        "data": {
          "type": "tax_categories",
          "id": "ABCRtyUpBa"
        }
      }
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the updated resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "avalara_accounts",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN"
    },
    "attributes": {
      "name": "Personal tax calculator",
      "type": "avalara_accounts",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      },
      "username": "user@mydomain.com",
      "company_code": "MYCOMPANY",
      "commit_invoice": true,
      "ddp": true
    },
    "relationships": {
      "markets": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/relationships/markets",
          "related": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/markets"
        }
      },
      "attachments": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/relationships/attachments",
          "related": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/attachments"
        }
      },
      "events": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/relationships/events",
          "related": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/events"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/event_stores"
        }
      },
      "tax_categories": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/relationships/tax_categories",
          "related": "https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN/tax_categories"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Delete an avalara account

How to delete an existing avalara account via API

To [delete](https://docs.commercelayer.io/core/deleting-resources) an avalara account, send a `DELETE` request to the `/api/avalara_accounts/:id` endpoint, where `id` is the id of the avalara account that you want to delete.

## Request

**DELETE** <https://yourdomain.commercelayer.io/api/avalara\\_accounts/:id>

### Example

{% tabs %}
{% tab title="Request" %}
The following request tries to delete the avalara account identified by the ID "XAyRWNUzyN":

```shell
curl -g -X DELETE \
  'https://yourdomain.commercelayer.io/api/avalara_accounts/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `204 No Content` status code.
{% endtab %}
{% endtabs %}


# Axerve gateways

The Axerve gateway object and the allowed CRUD operations on the related resource endpoint

Configuring an Axerve payment gateway for a market lets you safely process payments through [Axerve](https://www.axerve.com/en). The Axerve gateway is compliant with the PSD2 European regulation so that you can implement a payment flow that supports SCA and 3DS2 by using the Axerve [Lightbox](https://docs.axerve.com/en/integration-types/lightbox/) solution.

To create an Axerve gateway choose a meaningful name that helps you identify it within your organization and gather all the credentials requested (like the login ID and the gateway's API key, etc. — contact [Axerve's support](https://www.axerve.com/en/support) if you are not sure about the requested data).

<details>

<summary>How-to</summary>

Check the related [guide](/how-tos/placing-orders/payments/axerve) to learn more about how Commerce Layer handles the server-side part of the integration process with Axerve.

</details>


# The axerve gateway object

A comprehensive list of the axerve gateway resource's attributes and relationships

An axerve gateway object is returned as part of the response body of each successful list, retrieve, create or update API call to the `/api/axerve_gateways` endpoint.

## Fields

| Field                                 | Type      | Description                                                                                                                                                                                         |
| ------------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **type**                              | `string`  | `axerve_gateways`                                                                                                                                                                                   |
| **id**                                | `string`  | The axerve gateway unique identifier                                                                                                                                                                |
| links.**self**                        | `string`  | The axerve gateway endpoint URL                                                                                                                                                                     |
| attributes.**name**                   | `string`  | The payment gateway's internal name.                                                                                                                                                                |
| attributes.**force\_payments**        | `boolean` | Indicates if the payment source is forced on the editable order upon receiving a successful event from the gateway.                                                                                 |
| attributes.**credential\_keys**       | `object`  | The payment gateway's API credential keys last digits.                                                                                                                                              |
| attributes.**\_disable**              | `boolean` | Send this attribute if you want to mark this resource as disabled.                                                                                                                                  |
| attributes.**\_enable**               | `boolean` | Send this attribute if you want to mark this resource as enabled.                                                                                                                                   |
| attributes.**disabled\_at**           | `string`  | Time at which this resource was disabled.                                                                                                                                                           |
| attributes.**created\_at**            | `string`  | Time at which the resource was created.                                                                                                                                                             |
| attributes.**updated\_at**            | `string`  | Time at which the resource was last updated.                                                                                                                                                        |
| attributes.**reference**              | `string`  | A string that you can use to add any external identifier to the resource. This can be useful for integrating the resource to an external system, like an ERP, a marketing tool, a CRM, or whatever. |
| attributes.**reference\_origin**      | `string`  | Any identifier of the third party system that defines the reference code.                                                                                                                           |
| attributes.**metadata**               | `object`  | Set of key-value pairs that you can attach to the resource. This can be useful for storing additional information about the resource in a structured format.                                        |
| attributes.**login**                  | `string`  | The merchant login code.                                                                                                                                                                            |
| attributes.**api\_key**               | `string`  | The gateway API key.                                                                                                                                                                                |
| attributes.**webhook\_endpoint\_url** | `string`  | The gateway webhook URL, generated automatically.                                                                                                                                                   |
| relationships.**payment\_methods**    | `array`   | The associated payment methods.                                                                                                                                                                     |
| relationships.**event\_stores**       | `array`   | The associated event stores.                                                                                                                                                                        |
| relationships.**axerve\_payments**    | `array`   | The associated payments.                                                                                                                                                                            |
| meta.**mode**                         | `string`  | The resource environment (can be one of `test` or `live`)                                                                                                                                           |


# Create an axerve gateway

How to create an axerve gateway via API

To [create](https://docs.commercelayer.io/core/creating-resources) a new axerve gateway, send a `POST` request to the `/api/axerve_gateways` endpoint, passing the resource arguments in the request body.

## Request

**POST** <https://yourdomain.commercelayer.io/api/axerve\\_gateways>

### Arguments

| Body Parameter                     | Type      | Required                     |
| ---------------------------------- | --------- | ---------------------------- |
| **type**                           | `string`  | Required                     |
| attributes.**name**                | `string`  | Required                     |
| attributes.**force\_payments**     | `boolean` | Optional, default is 'false' |
| attributes.**\_disable**           | `boolean` | Optional                     |
| attributes.**\_enable**            | `boolean` | Optional                     |
| attributes.**reference**           | `string`  | Optional                     |
| attributes.**reference\_origin**   | `string`  | Optional                     |
| attributes.**metadata**            | `object`  | Optional                     |
| attributes.**login**               | `string`  | Required                     |
| attributes.**api\_key**            | `string`  | Required                     |
| relationships.**axerve\_payments** | `array`   | Optional                     |

### Example

{% tabs %}
{% tab title="Request" %}
The following request creates a new axerve gateway:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/axerve_gateways' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "axerve_gateways",
    "attributes": {
      "name": "US payment gateway",
      "login": "xxxx-yyyy-zzzz",
      "api_key": "xxxx-yyyy-zzzz"
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "axerve_gateways",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN"
    },
    "attributes": {
      "name": "US payment gateway",
      "force_payments": true,
      "credential_keys": {
        "api_key": "********BW989"
      },
      "disabled_at": "2018-01-01T12:00:00.000Z",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      },
      "login": "xxxx-yyyy-zzzz",
      "webhook_endpoint_url": "https://core.commercelayer.co/webhook_callbacks/axerve_gateways/xxxxx"
    },
    "relationships": {
      "payment_methods": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/relationships/payment_methods",
          "related": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/payment_methods"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/event_stores"
        }
      },
      "axerve_payments": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/relationships/axerve_payments",
          "related": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/axerve_payments"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# List all axerve gateways

How to fetch a collection of axerve gateways via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a collection of axerve gateways, send a `GET` request to the `/api/axerve_gateways` endpoint.

## Request

**GET** <https://yourdomain.commercelayer.io/api/axerve\\_gateways>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches a collection of axerve gateways:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/axerve_gateways/' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of resource objects:

```json
{
  "data": [
    {
      "id": "XAyRWNUzyN",
      "type": "axerve_gateways",
      "links": {
        "self": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN"
      },
      "attributes": {
        "name": "US payment gateway",
        "force_payments": true,
        "credential_keys": {
          "api_key": "********BW989"
        },
        "disabled_at": "2018-01-01T12:00:00.000Z",
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": "ANY-EXTERNAL-REFEFERNCE",
        "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
        "metadata": {
          "foo": "bar"
        },
        "login": "xxxx-yyyy-zzzz",
        "webhook_endpoint_url": "https://core.commercelayer.co/webhook_callbacks/axerve_gateways/xxxxx"
      },
      "relationships": {
        "payment_methods": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/relationships/payment_methods",
            "related": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/payment_methods"
          }
        },
        "event_stores": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/relationships/event_stores",
            "related": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/event_stores"
          }
        },
        "axerve_payments": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/relationships/axerve_payments",
            "related": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/axerve_payments"
          }
        }
      },
      "meta": {
        "mode": "test",
        "organization_id": "xRRkjDFafe",
        "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
      }
    },
    {
      "other": "... 9 axerve_gateways (first page)"
    }
  ],
  "meta": {
    "record_count": 140,
    "page_count": 14
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/axerve_gateways?page[number]=1&page[size]=10",
    "next": "https://yourdomain.commercelayer.io/api/axerve_gateways?page[number]=2&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/axerve_gateways?page[number]=14&page[size]=10"
  }
}
```

{% endtab %}
{% endtabs %}

Remember that when you fetch a list of resources you get [paginated](https://docs.commercelayer.io/core/pagination) result.

### Sortable fields

The list of axerve gateways can be [sorted](https://docs.commercelayer.io/core/sorting-results) by the following fields:

#### Attributes

* `name`
* `id`
* `disabled_at`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`

### Filterable fields

The list of axerve gateways can be [filtered](https://docs.commercelayer.io/core/filtering-data) by the following fields:

#### Attributes

* `name`
* `id`
* `disabled_at`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`
* `metadata`

#### Relationships

* `payment_methods`
* `axerve_payments`


# Retrieve an axerve gateway

How to fetch a specific axerve gateway via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a single axerve gateway, send a `GET` request to the `/api/axerve_gateways/:id` endpoint, where `id` is the ID of the resource that you want to retrieve.

## Request

**GET** <https://yourdomain.commercelayer.io/api/axerve\\_gateways/:id>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches the axerve gateway identified by the ID "XAyRWNUzyN":

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a single resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "axerve_gateways",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN"
    },
    "attributes": {
      "name": "US payment gateway",
      "force_payments": true,
      "credential_keys": {
        "api_key": "********BW989"
      },
      "disabled_at": "2018-01-01T12:00:00.000Z",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      },
      "login": "xxxx-yyyy-zzzz",
      "webhook_endpoint_url": "https://core.commercelayer.co/webhook_callbacks/axerve_gateways/xxxxx"
    },
    "relationships": {
      "payment_methods": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/relationships/payment_methods",
          "related": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/payment_methods"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/event_stores"
        }
      },
      "axerve_payments": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/relationships/axerve_payments",
          "related": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/axerve_payments"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Update an axerve gateway

How to update an existing axerve gateway via API

To [update](https://docs.commercelayer.io/core/updating-resources) an existing axerve gateway, send a `PATCH` request to the `/api/axerve_gateways/:id` endpoint, where `id` is the ID of the resource that you want to update.

Here below the list of all the possible arguments that you can pass with the request body.

## Request

**PATCH** <https://yourdomain.commercelayer.io/api/axerve\\_gateways/:id>

### Arguments

| Body Parameter                     | Type      | Required |
| ---------------------------------- | --------- | -------- |
| **type**                           | `string`  | Required |
| **id**                             | `string`  | Required |
| attributes.**name**                | `string`  | Optional |
| attributes.**force\_payments**     | `boolean` | Optional |
| attributes.**\_disable**           | `boolean` | Optional |
| attributes.**\_enable**            | `boolean` | Optional |
| attributes.**reference**           | `string`  | Optional |
| attributes.**reference\_origin**   | `string`  | Optional |
| attributes.**metadata**            | `object`  | Optional |
| attributes.**login**               | `string`  | Optional |
| attributes.**api\_key**            | `string`  | Optional |
| relationships.**axerve\_payments** | `array`   | Optional |

### Example

{% tabs %}
{% tab title="Request" %}
The following request updates the axerve gateway identified by the ID "XAyRWNUzyN":

```shell
curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "axerve_gateways",
    "id": "xYZkjABcde",
    "attributes": {
      "_disable": true
    },
    "relationships": {
      "axerve_payments": {
        "data": {
          "type": "axerve_payments",
          "id": "ABCRtyUpBa"
        }
      }
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the updated resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "axerve_gateways",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN"
    },
    "attributes": {
      "name": "US payment gateway",
      "force_payments": true,
      "credential_keys": {
        "api_key": "********BW989"
      },
      "disabled_at": "2018-01-01T12:00:00.000Z",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      },
      "login": "xxxx-yyyy-zzzz",
      "webhook_endpoint_url": "https://core.commercelayer.co/webhook_callbacks/axerve_gateways/xxxxx"
    },
    "relationships": {
      "payment_methods": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/relationships/payment_methods",
          "related": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/payment_methods"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/event_stores"
        }
      },
      "axerve_payments": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/relationships/axerve_payments",
          "related": "https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN/axerve_payments"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Delete an axerve gateway

How to delete an existing axerve gateway via API

To [delete](https://docs.commercelayer.io/core/deleting-resources) an axerve gateway, send a `DELETE` request to the `/api/axerve_gateways/:id` endpoint, where `id` is the id of the axerve gateway that you want to delete.

## Request

**DELETE** <https://yourdomain.commercelayer.io/api/axerve\\_gateways/:id>

### Example

{% tabs %}
{% tab title="Request" %}
The following request tries to delete the axerve gateway identified by the ID "XAyRWNUzyN":

```shell
curl -g -X DELETE \
  'https://yourdomain.commercelayer.io/api/axerve_gateways/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `204 No Content` status code.
{% endtab %}
{% endtabs %}


# Axerve payments

The Axerve payment object and the allowed CRUD operations on the related resource endpoint

Axerve payments are a type of payment source that lets you process payments through [Axerve gateways](/core-api-reference/axerve_gateways).

Axerve payments can be easily created (you just need to pass a valid `return_url`) and [associated with an order](https://docs.commercelayer.io/core-api-reference/spaces/-Lk-ezuDClaMavTqnRi0/pages/DTN24kDvLyE7wH0zuOhE#2.-create-the-payment-source-and-associate-it-with-the-order). Once you have created a payment source for Axerve and you're going to process the payment, if you're not sure whether the order changed in the meanwhile or not you can [update the payment intent](/how-tos/placing-orders/payments/axerve/updating-the-payment-intent) with the latest order amount by passing the `_update` trigger attribute.


# The axerve payment object

A comprehensive list of the axerve payment resource's attributes and relationships

An axerve payment object is returned as part of the response body of each successful list, retrieve, create or update API call to the `/api/axerve_payments` endpoint.

## Fields

| Field                                 | Type      | Description                                                                                                                                                                                         |
| ------------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **type**                              | `string`  | `axerve_payments`                                                                                                                                                                                   |
| **id**                                | `string`  | The axerve payment unique identifier                                                                                                                                                                |
| links.**self**                        | `string`  | The axerve payment endpoint URL                                                                                                                                                                     |
| attributes.**login**                  | `string`  | The merchant login code.                                                                                                                                                                            |
| attributes.**return\_url**            | `string`  | The URL where the payer is redirected after they approve the payment.                                                                                                                               |
| attributes.**payment\_request\_data** | `object`  | The Axerve payment request data, collected by client.                                                                                                                                               |
| attributes.**client\_ip**             | `string`  | The IP adress of the client creating the payment.                                                                                                                                                   |
| attributes.**buyer\_details**         | `object`  | The details of the buyer creating the payment.                                                                                                                                                      |
| attributes.**request\_token**         | `boolean` | Requires the creation of a token to represent this payment, mandatory to use customer's wallet and order subscriptions.                                                                             |
| attributes.**mismatched\_amounts**    | `boolean` | Indicates if the order current amount differs form the one of the associated authorization.                                                                                                         |
| attributes.**\_update**               | `boolean` | Send this attribute if you want to update the payment with fresh order data.                                                                                                                        |
| attributes.**payment\_instrument**    | `object`  | Information about the payment instrument used in the transaction.                                                                                                                                   |
| attributes.**created\_at**            | `string`  | Time at which the resource was created.                                                                                                                                                             |
| attributes.**updated\_at**            | `string`  | Time at which the resource was last updated.                                                                                                                                                        |
| attributes.**reference**              | `string`  | A string that you can use to add any external identifier to the resource. This can be useful for integrating the resource to an external system, like an ERP, a marketing tool, a CRM, or whatever. |
| attributes.**reference\_origin**      | `string`  | Any identifier of the third party system that defines the reference code.                                                                                                                           |
| attributes.**metadata**               | `object`  | Set of key-value pairs that you can attach to the resource. This can be useful for storing additional information about the resource in a structured format.                                        |
| relationships.**order**               | `object`  | The order associated to the adyen payment, that is set as its payment source.                                                                                                                       |
| relationships.**payment\_gateway**    | `object`  | The associated payment gateway, inherited by the order payment\_method.                                                                                                                             |
| relationships.**event\_stores**       | `array`   | The associated event stores.                                                                                                                                                                        |
| meta.**mode**                         | `string`  | The resource environment (can be one of `test` or `live`)                                                                                                                                           |


# Create an axerve payment

How to create an axerve payment via API

To [create](https://docs.commercelayer.io/core/creating-resources) a new axerve payment, send a `POST` request to the `/api/axerve_payments` endpoint, passing the resource arguments in the request body.

## Request

**POST** <https://yourdomain.commercelayer.io/api/axerve\\_payments>

### Arguments

| Body Parameter                   | Type      | Required                     |
| -------------------------------- | --------- | ---------------------------- |
| **type**                         | `string`  | Required                     |
| attributes.**return\_url**       | `string`  | Required                     |
| attributes.**client\_ip**        | `string`  | Optional                     |
| attributes.**buyer\_details**    | `object`  | Optional                     |
| attributes.**request\_token**    | `boolean` | Optional, default is 'false' |
| attributes.**reference**         | `string`  | Optional                     |
| attributes.**reference\_origin** | `string`  | Optional                     |
| attributes.**metadata**          | `object`  | Optional                     |
| relationships.**order**          | `object`  | Required                     |

### Example

{% tabs %}
{% tab title="Request" %}
The following request creates a new axerve payment:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/axerve_payments' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "axerve_payments",
    "attributes": {
      "return_url": "https://yourdomain.com/thankyou"
    },
    "relationships": {
      "order": {
        "data": {
          "type": "orders",
          "id": "ABCRtyUpBa"
        }
      }
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "axerve_payments",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN"
    },
    "attributes": {
      "login": "xxxx-yyyy-zzzz",
      "return_url": "https://yourdomain.com/thankyou",
      "payment_request_data": {
        "foo": "bar"
      },
      "client_ip": "213.45.120.5",
      "buyer_details": {
        "cardHolder": {
          "email": "george.harrison@gmail.com"
        },
        "shippingAddress": {
          "firstName": "George"
        }
      },
      "request_token": true,
      "mismatched_amounts": false,
      "payment_instrument": {
        "issuer": "cl bank",
        "card_type": "visa"
      },
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "order": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/relationships/order",
          "related": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/order"
        }
      },
      "payment_gateway": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/relationships/payment_gateway",
          "related": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/payment_gateway"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# List all axerve payments

How to fetch a collection of axerve payments via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a collection of axerve payments, send a `GET` request to the `/api/axerve_payments` endpoint.

## Request

**GET** <https://yourdomain.commercelayer.io/api/axerve\\_payments>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches a collection of axerve payments:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/axerve_payments/' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of resource objects:

```json
{
  "data": [
    {
      "id": "XAyRWNUzyN",
      "type": "axerve_payments",
      "links": {
        "self": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN"
      },
      "attributes": {
        "login": "xxxx-yyyy-zzzz",
        "return_url": "https://yourdomain.com/thankyou",
        "payment_request_data": {
          "foo": "bar"
        },
        "client_ip": "213.45.120.5",
        "buyer_details": {
          "cardHolder": {
            "email": "george.harrison@gmail.com"
          },
          "shippingAddress": {
            "firstName": "George"
          }
        },
        "request_token": true,
        "mismatched_amounts": false,
        "payment_instrument": {
          "issuer": "cl bank",
          "card_type": "visa"
        },
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": "ANY-EXTERNAL-REFEFERNCE",
        "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
        "metadata": {
          "foo": "bar"
        }
      },
      "relationships": {
        "order": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/relationships/order",
            "related": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/order"
          }
        },
        "payment_gateway": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/relationships/payment_gateway",
            "related": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/payment_gateway"
          }
        },
        "event_stores": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/relationships/event_stores",
            "related": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/event_stores"
          }
        }
      },
      "meta": {
        "mode": "test",
        "organization_id": "xRRkjDFafe",
        "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
      }
    },
    {
      "other": "... 9 axerve_payments (first page)"
    }
  ],
  "meta": {
    "record_count": 140,
    "page_count": 14
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/axerve_payments?page[number]=1&page[size]=10",
    "next": "https://yourdomain.commercelayer.io/api/axerve_payments?page[number]=2&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/axerve_payments?page[number]=14&page[size]=10"
  }
}
```

{% endtab %}
{% endtabs %}

Remember that when you fetch a list of resources you get [paginated](https://docs.commercelayer.io/core/pagination) result.

### Sortable fields

The list of axerve payments can be [sorted](https://docs.commercelayer.io/core/sorting-results) by the following fields:

#### Attributes

* `id`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`

#### Relationships

* `order`

### Filterable fields

The list of axerve payments can be [filtered](https://docs.commercelayer.io/core/filtering-data) by the following fields:

#### Attributes

* `id`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`
* `metadata`

#### Relationships

* `order`


# Retrieve an axerve payment

How to fetch a specific axerve payment via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a single axerve payment, send a `GET` request to the `/api/axerve_payments/:id` endpoint, where `id` is the ID of the resource that you want to retrieve.

## Request

**GET** <https://yourdomain.commercelayer.io/api/axerve\\_payments/:id>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches the axerve payment identified by the ID "XAyRWNUzyN":

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a single resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "axerve_payments",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN"
    },
    "attributes": {
      "login": "xxxx-yyyy-zzzz",
      "return_url": "https://yourdomain.com/thankyou",
      "payment_request_data": {
        "foo": "bar"
      },
      "client_ip": "213.45.120.5",
      "buyer_details": {
        "cardHolder": {
          "email": "george.harrison@gmail.com"
        },
        "shippingAddress": {
          "firstName": "George"
        }
      },
      "request_token": true,
      "mismatched_amounts": false,
      "payment_instrument": {
        "issuer": "cl bank",
        "card_type": "visa"
      },
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "order": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/relationships/order",
          "related": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/order"
        }
      },
      "payment_gateway": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/relationships/payment_gateway",
          "related": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/payment_gateway"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Update an axerve payment

How to update an existing axerve payment via API

To [update](https://docs.commercelayer.io/core/updating-resources) an existing axerve payment, send a `PATCH` request to the `/api/axerve_payments/:id` endpoint, where `id` is the ID of the resource that you want to update.

Here below the list of all the possible arguments that you can pass with the request body.

## Request

**PATCH** <https://yourdomain.commercelayer.io/api/axerve\\_payments/:id>

### Arguments

| Body Parameter                        | Type      | Required |
| ------------------------------------- | --------- | -------- |
| **type**                              | `string`  | Required |
| **id**                                | `string`  | Required |
| attributes.**payment\_request\_data** | `object`  | Optional |
| attributes.**\_update**               | `boolean` | Optional |
| attributes.**reference**              | `string`  | Optional |
| attributes.**reference\_origin**      | `string`  | Optional |
| attributes.**metadata**               | `object`  | Optional |
| relationships.**order**               | `object`  | Optional |

### Example

{% tabs %}
{% tab title="Request" %}
The following request updates the axerve payment identified by the ID "XAyRWNUzyN":

```shell
curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "axerve_payments",
    "id": "xYZkjABcde",
    "attributes": {
      "payment_request_data": {
        "foo": "bar"
      }
    },
    "relationships": {
      "order": {
        "data": {
          "type": "orders",
          "id": "ABCRtyUpBa"
        }
      }
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the updated resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "axerve_payments",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN"
    },
    "attributes": {
      "login": "xxxx-yyyy-zzzz",
      "return_url": "https://yourdomain.com/thankyou",
      "payment_request_data": {
        "foo": "bar"
      },
      "client_ip": "213.45.120.5",
      "buyer_details": {
        "cardHolder": {
          "email": "george.harrison@gmail.com"
        },
        "shippingAddress": {
          "firstName": "George"
        }
      },
      "request_token": true,
      "mismatched_amounts": false,
      "payment_instrument": {
        "issuer": "cl bank",
        "card_type": "visa"
      },
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "order": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/relationships/order",
          "related": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/order"
        }
      },
      "payment_gateway": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/relationships/payment_gateway",
          "related": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/payment_gateway"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Delete an axerve payment

How to delete an existing axerve payment via API

To [delete](https://docs.commercelayer.io/core/deleting-resources) an axerve payment, send a `DELETE` request to the `/api/axerve_payments/:id` endpoint, where `id` is the id of the axerve payment that you want to delete.

## Request

**DELETE** <https://yourdomain.commercelayer.io/api/axerve\\_payments/:id>

### Example

{% tabs %}
{% tab title="Request" %}
The following request tries to delete the axerve payment identified by the ID "XAyRWNUzyN":

```shell
curl -g -X DELETE \
  'https://yourdomain.commercelayer.io/api/axerve_payments/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `204 No Content` status code.
{% endtab %}
{% endtabs %}


# Bing geocoders

The Bing geocoder object and the allowed CRUD operations on the related resource endpoint

[Geocoders](/core-api-reference/geocoders) lets you convert an address in text form into geographic coordinates (like latitude and longitude). A geocoder can be optionally associated with a market. By connecting a geocoder to a market, all the shipping and billing addresses belonging to that market orders will be geocoded.

To create a **Bing** geocoder choose a meaningful name that helps you identify it within your organization and add your [Bing Maps](https://docs.microsoft.com/en-us/bingmaps/rest-services/locations/) API key.

Commerce Layer also supports [Google](/core-api-reference/google_geocoders) geocoder integration.


# The bing geocoder object

A comprehensive list of the bing geocoder resource's attributes and relationships

A bing geocoder object is returned as part of the response body of each successful list, retrieve, create or update API call to the `/api/bing_geocoders` endpoint.

## Fields

| Field                            | Type     | Description                                                                                                                                                                                         |
| -------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **type**                         | `string` | `bing_geocoders`                                                                                                                                                                                    |
| **id**                           | `string` | The bing geocoder unique identifier                                                                                                                                                                 |
| links.**self**                   | `string` | The bing geocoder endpoint URL                                                                                                                                                                      |
| attributes.**name**              | `string` | The geocoder's internal name.                                                                                                                                                                       |
| attributes.**created\_at**       | `string` | Time at which the resource was created.                                                                                                                                                             |
| attributes.**updated\_at**       | `string` | Time at which the resource was last updated.                                                                                                                                                        |
| attributes.**reference**         | `string` | A string that you can use to add any external identifier to the resource. This can be useful for integrating the resource to an external system, like an ERP, a marketing tool, a CRM, or whatever. |
| attributes.**reference\_origin** | `string` | Any identifier of the third party system that defines the reference code.                                                                                                                           |
| attributes.**metadata**          | `object` | Set of key-value pairs that you can attach to the resource. This can be useful for storing additional information about the resource in a structured format.                                        |
| attributes.**key**               | `string` | The Bing Virtualearth key.                                                                                                                                                                          |
| relationships.**markets**        | `array`  | The associated markets.                                                                                                                                                                             |
| relationships.**addresses**      | `array`  | The associated addresses.                                                                                                                                                                           |
| relationships.**attachments**    | `array`  | The associated attachments.                                                                                                                                                                         |
| relationships.**event\_stores**  | `array`  | The associated event stores.                                                                                                                                                                        |
| meta.**mode**                    | `string` | The resource environment (can be one of `test` or `live`)                                                                                                                                           |


# Create a bing geocoder

How to create a bing geocoder via API

To [create](https://docs.commercelayer.io/core/creating-resources) a new bing geocoder, send a `POST` request to the `/api/bing_geocoders` endpoint, passing the resource arguments in the request body.

## Request

**POST** <https://yourdomain.commercelayer.io/api/bing\\_geocoders>

### Arguments

| Body Parameter                   | Type     | Required |
| -------------------------------- | -------- | -------- |
| **type**                         | `string` | Required |
| attributes.**name**              | `string` | Required |
| attributes.**reference**         | `string` | Optional |
| attributes.**reference\_origin** | `string` | Optional |
| attributes.**metadata**          | `object` | Optional |
| attributes.**key**               | `string` | Required |

### Example

{% tabs %}
{% tab title="Request" %}
The following request creates a new bing geocoder:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/bing_geocoders' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "bing_geocoders",
    "attributes": {
      "name": "Default geocoder",
      "key": "xxxx-yyyy-zzzz"
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "bing_geocoders",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN"
    },
    "attributes": {
      "name": "Default geocoder",
      "type": "google_geocoders",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "markets": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/relationships/markets",
          "related": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/markets"
        }
      },
      "addresses": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/relationships/addresses",
          "related": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/addresses"
        }
      },
      "attachments": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/relationships/attachments",
          "related": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/attachments"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# List all bing geocoders

How to fetch a collection of bing geocoders via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a collection of bing geocoders, send a `GET` request to the `/api/bing_geocoders` endpoint.

## Request

**GET** <https://yourdomain.commercelayer.io/api/bing\\_geocoders>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches a collection of bing geocoders:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/bing_geocoders/' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of resource objects:

```json
{
  "data": [
    {
      "id": "XAyRWNUzyN",
      "type": "bing_geocoders",
      "links": {
        "self": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN"
      },
      "attributes": {
        "name": "Default geocoder",
        "type": "google_geocoders",
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": "ANY-EXTERNAL-REFEFERNCE",
        "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
        "metadata": {
          "foo": "bar"
        }
      },
      "relationships": {
        "markets": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/relationships/markets",
            "related": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/markets"
          }
        },
        "addresses": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/relationships/addresses",
            "related": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/addresses"
          }
        },
        "attachments": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/relationships/attachments",
            "related": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/attachments"
          }
        },
        "event_stores": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/relationships/event_stores",
            "related": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/event_stores"
          }
        }
      },
      "meta": {
        "mode": "test",
        "organization_id": "xRRkjDFafe",
        "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
      }
    },
    {
      "other": "... 9 bing_geocoders (first page)"
    }
  ],
  "meta": {
    "record_count": 140,
    "page_count": 14
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/bing_geocoders?page[number]=1&page[size]=10",
    "next": "https://yourdomain.commercelayer.io/api/bing_geocoders?page[number]=2&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/bing_geocoders?page[number]=14&page[size]=10"
  }
}
```

{% endtab %}
{% endtabs %}

Remember that when you fetch a list of resources you get [paginated](https://docs.commercelayer.io/core/pagination) result.

### Sortable fields

The list of bing geocoders can be [sorted](https://docs.commercelayer.io/core/sorting-results) by the following fields:

#### Attributes

* `name`
* `type`
* `id`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`

### Filterable fields

The list of bing geocoders can be [filtered](https://docs.commercelayer.io/core/filtering-data) by the following fields:

#### Attributes

* `name`
* `type`
* `id`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`
* `metadata`

#### Relationships

* `attachments`


# Retrieve a bing geocoder

How to fetch a specific bing geocoder via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a single bing geocoder, send a `GET` request to the `/api/bing_geocoders/:id` endpoint, where `id` is the ID of the resource that you want to retrieve.

## Request

**GET** <https://yourdomain.commercelayer.io/api/bing\\_geocoders/:id>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches the bing geocoder identified by the ID "XAyRWNUzyN":

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a single resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "bing_geocoders",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN"
    },
    "attributes": {
      "name": "Default geocoder",
      "type": "google_geocoders",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "markets": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/relationships/markets",
          "related": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/markets"
        }
      },
      "addresses": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/relationships/addresses",
          "related": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/addresses"
        }
      },
      "attachments": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/relationships/attachments",
          "related": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/attachments"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Update a bing geocoder

How to update an existing bing geocoder via API

To [update](https://docs.commercelayer.io/core/updating-resources) an existing bing geocoder, send a `PATCH` request to the `/api/bing_geocoders/:id` endpoint, where `id` is the ID of the resource that you want to update.

Here below the list of all the possible arguments that you can pass with the request body.

## Request

**PATCH** <https://yourdomain.commercelayer.io/api/bing\\_geocoders/:id>

### Arguments

| Body Parameter                   | Type     | Required |
| -------------------------------- | -------- | -------- |
| **type**                         | `string` | Required |
| **id**                           | `string` | Required |
| attributes.**name**              | `string` | Optional |
| attributes.**reference**         | `string` | Optional |
| attributes.**reference\_origin** | `string` | Optional |
| attributes.**metadata**          | `object` | Optional |
| attributes.**key**               | `string` | Optional |

### Example

{% tabs %}
{% tab title="Request" %}
The following request updates the bing geocoder identified by the ID "XAyRWNUzyN":

```shell
curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "bing_geocoders",
    "id": "xYZkjABcde",
    "attributes": {
      "reference": "ANY-EXTERNAL-REFEFERNCE"
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the updated resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "bing_geocoders",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN"
    },
    "attributes": {
      "name": "Default geocoder",
      "type": "google_geocoders",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "markets": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/relationships/markets",
          "related": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/markets"
        }
      },
      "addresses": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/relationships/addresses",
          "related": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/addresses"
        }
      },
      "attachments": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/relationships/attachments",
          "related": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/attachments"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Delete a bing geocoder

How to delete an existing bing geocoder via API

To [delete](https://docs.commercelayer.io/core/deleting-resources) a bing geocoder, send a `DELETE` request to the `/api/bing_geocoders/:id` endpoint, where `id` is the id of the bing geocoder that you want to delete.

## Request

**DELETE** <https://yourdomain.commercelayer.io/api/bing\\_geocoders/:id>

### Example

{% tabs %}
{% tab title="Request" %}
The following request tries to delete the bing geocoder identified by the ID "XAyRWNUzyN":

```shell
curl -g -X DELETE \
  'https://yourdomain.commercelayer.io/api/bing_geocoders/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `204 No Content` status code.
{% endtab %}
{% endtabs %}


# Braintree gateways

The Braintree gateway object and the allowed CRUD operations on the related resource endpoint

Configuring a Braintree payment gateway for a market lets you safely process payments through [Braintree](https://developer.paypal.com/braintree/docs). The Braintree gateway is compliant with the PSD2 European regulation so that you can implement a payment flow that supports SCA and 3DS2 by using the Braintree official JS SDK and libraries.

To create a Braintree gateway choose a meaningful name that helps you identify it within your organization and gather all the [credentials](https://developer.paypal.com/braintree/articles/control-panel/important-gateway-credentials) requested (like merchant and merchant account IDs, public and private keys, etc. — contact [Braintree's support](https://developer.paypal.com/braintree/help) if you are not sure about the requested data).

<details>

<summary>How-to</summary>

Check the related [guide](https://docs.commercelayer.io/developers/v/how-tos/payments/braintree) to learn more on how Commerce Layer handles the server-side part of the integration process with Braintree.

</details>


# The braintree gateway object

A comprehensive list of the braintree gateway resource's attributes and relationships

A braintree gateway object is returned as part of the response body of each successful list, retrieve, create or update API call to the `/api/braintree_gateways` endpoint.

## Fields

| Field                                 | Type      | Description                                                                                                                                                                                         |
| ------------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **type**                              | `string`  | `braintree_gateways`                                                                                                                                                                                |
| **id**                                | `string`  | The braintree gateway unique identifier                                                                                                                                                             |
| links.**self**                        | `string`  | The braintree gateway endpoint URL                                                                                                                                                                  |
| attributes.**name**                   | `string`  | The payment gateway's internal name.                                                                                                                                                                |
| attributes.**force\_payments**        | `boolean` | Indicates if the payment source is forced on the editable order upon receiving a successful event from the gateway.                                                                                 |
| attributes.**credential\_keys**       | `object`  | The payment gateway's API credential keys last digits.                                                                                                                                              |
| attributes.**\_disable**              | `boolean` | Send this attribute if you want to mark this resource as disabled.                                                                                                                                  |
| attributes.**\_enable**               | `boolean` | Send this attribute if you want to mark this resource as enabled.                                                                                                                                   |
| attributes.**disabled\_at**           | `string`  | Time at which this resource was disabled.                                                                                                                                                           |
| attributes.**created\_at**            | `string`  | Time at which the resource was created.                                                                                                                                                             |
| attributes.**updated\_at**            | `string`  | Time at which the resource was last updated.                                                                                                                                                        |
| attributes.**reference**              | `string`  | A string that you can use to add any external identifier to the resource. This can be useful for integrating the resource to an external system, like an ERP, a marketing tool, a CRM, or whatever. |
| attributes.**reference\_origin**      | `string`  | Any identifier of the third party system that defines the reference code.                                                                                                                           |
| attributes.**metadata**               | `object`  | Set of key-value pairs that you can attach to the resource. This can be useful for storing additional information about the resource in a structured format.                                        |
| attributes.**\_check**                | `boolean` | Send this attribute if you want to check the credentials against the payment gateway's APIs.                                                                                                        |
| attributes.**merchant\_account\_id**  | `string`  | The gateway merchant account ID.                                                                                                                                                                    |
| attributes.**merchant\_id**           | `string`  | The gateway merchant ID.                                                                                                                                                                            |
| attributes.**public\_key**            | `string`  | The gateway API public key.                                                                                                                                                                         |
| attributes.**private\_key**           | `string`  | The gateway API private key.                                                                                                                                                                        |
| attributes.**descriptor\_name**       | `string`  | The dynamic descriptor name. Must be composed by business name (3, 7 or 12 chars), an asterisk (\*) and the product name (18, 14 or 9 chars), for a total length of 22 chars.                       |
| attributes.**descriptor\_phone**      | `string`  | The dynamic descriptor phone number. Must be 10-14 characters and can only contain numbers, dashes, parentheses and periods.                                                                        |
| attributes.**descriptor\_url**        | `string`  | The dynamic descriptor URL.                                                                                                                                                                         |
| attributes.**webhook\_endpoint\_url** | `string`  | The gateway webhook URL, generated automatically.                                                                                                                                                   |
| relationships.**payment\_methods**    | `array`   | The associated payment methods.                                                                                                                                                                     |
| relationships.**event\_stores**       | `array`   | The associated event stores.                                                                                                                                                                        |
| relationships.**braintree\_payments** | `array`   | The associated payments.                                                                                                                                                                            |
| meta.**mode**                         | `string`  | The resource environment (can be one of `test` or `live`)                                                                                                                                           |


# Create a braintree gateway

How to create a braintree gateway via API

To [create](https://docs.commercelayer.io/core/creating-resources) a new braintree gateway, send a `POST` request to the `/api/braintree_gateways` endpoint, passing the resource arguments in the request body.

## Request

**POST** <https://yourdomain.commercelayer.io/api/braintree\\_gateways>

### Arguments

| Body Parameter                        | Type      | Required                     |
| ------------------------------------- | --------- | ---------------------------- |
| **type**                              | `string`  | Required                     |
| attributes.**name**                   | `string`  | Required                     |
| attributes.**force\_payments**        | `boolean` | Optional, default is 'false' |
| attributes.**\_disable**              | `boolean` | Optional                     |
| attributes.**\_enable**               | `boolean` | Optional                     |
| attributes.**reference**              | `string`  | Optional                     |
| attributes.**reference\_origin**      | `string`  | Optional                     |
| attributes.**metadata**               | `object`  | Optional                     |
| attributes.**\_check**                | `boolean` | Optional                     |
| attributes.**merchant\_account\_id**  | `string`  | Required                     |
| attributes.**merchant\_id**           | `string`  | Required                     |
| attributes.**public\_key**            | `string`  | Required                     |
| attributes.**private\_key**           | `string`  | Required                     |
| attributes.**descriptor\_name**       | `string`  | Optional                     |
| attributes.**descriptor\_phone**      | `string`  | Optional                     |
| attributes.**descriptor\_url**        | `string`  | Optional                     |
| relationships.**braintree\_payments** | `array`   | Optional                     |

### Example

{% tabs %}
{% tab title="Request" %}
The following request creates a new braintree gateway:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/braintree_gateways' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "braintree_gateways",
    "attributes": {
      "name": "US payment gateway",
      "merchant_account_id": "xxxx-yyyy-zzzz",
      "merchant_id": "xxxx-yyyy-zzzz",
      "public_key": "xxxx-yyyy-zzzz",
      "private_key": "xxxx-yyyy-zzzz"
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "braintree_gateways",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN"
    },
    "attributes": {
      "name": "US payment gateway",
      "force_payments": true,
      "credential_keys": {
        "api_key": "********BW989"
      },
      "disabled_at": "2018-01-01T12:00:00.000Z",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      },
      "descriptor_name": "company*productabc1234",
      "descriptor_phone": "3125551212",
      "descriptor_url": "company.com",
      "webhook_endpoint_url": "https://core.commercelayer.co/webhook_callbacks/braintree_gateways/xxxxx"
    },
    "relationships": {
      "payment_methods": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/relationships/payment_methods",
          "related": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/payment_methods"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/event_stores"
        }
      },
      "braintree_payments": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/relationships/braintree_payments",
          "related": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/braintree_payments"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# List all braintree gateways

How to fetch a collection of braintree gateways via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a collection of braintree gateways, send a `GET` request to the `/api/braintree_gateways` endpoint.

## Request

**GET** <https://yourdomain.commercelayer.io/api/braintree\\_gateways>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches a collection of braintree gateways:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/braintree_gateways/' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of resource objects:

```json
{
  "data": [
    {
      "id": "XAyRWNUzyN",
      "type": "braintree_gateways",
      "links": {
        "self": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN"
      },
      "attributes": {
        "name": "US payment gateway",
        "force_payments": true,
        "credential_keys": {
          "api_key": "********BW989"
        },
        "disabled_at": "2018-01-01T12:00:00.000Z",
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": "ANY-EXTERNAL-REFEFERNCE",
        "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
        "metadata": {
          "foo": "bar"
        },
        "descriptor_name": "company*productabc1234",
        "descriptor_phone": "3125551212",
        "descriptor_url": "company.com",
        "webhook_endpoint_url": "https://core.commercelayer.co/webhook_callbacks/braintree_gateways/xxxxx"
      },
      "relationships": {
        "payment_methods": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/relationships/payment_methods",
            "related": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/payment_methods"
          }
        },
        "event_stores": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/relationships/event_stores",
            "related": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/event_stores"
          }
        },
        "braintree_payments": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/relationships/braintree_payments",
            "related": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/braintree_payments"
          }
        }
      },
      "meta": {
        "mode": "test",
        "organization_id": "xRRkjDFafe",
        "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
      }
    },
    {
      "other": "... 9 braintree_gateways (first page)"
    }
  ],
  "meta": {
    "record_count": 140,
    "page_count": 14
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/braintree_gateways?page[number]=1&page[size]=10",
    "next": "https://yourdomain.commercelayer.io/api/braintree_gateways?page[number]=2&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/braintree_gateways?page[number]=14&page[size]=10"
  }
}
```

{% endtab %}
{% endtabs %}

Remember that when you fetch a list of resources you get [paginated](https://docs.commercelayer.io/core/pagination) result.

### Sortable fields

The list of braintree gateways can be [sorted](https://docs.commercelayer.io/core/sorting-results) by the following fields:

#### Attributes

* `name`
* `id`
* `disabled_at`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`

### Filterable fields

The list of braintree gateways can be [filtered](https://docs.commercelayer.io/core/filtering-data) by the following fields:

#### Attributes

* `name`
* `id`
* `disabled_at`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`
* `metadata`

#### Relationships

* `payment_methods`
* `braintree_payments`


# Retrieve a braintree gateway

How to fetch a specific braintree gateway via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a single braintree gateway, send a `GET` request to the `/api/braintree_gateways/:id` endpoint, where `id` is the ID of the resource that you want to retrieve.

## Request

**GET** <https://yourdomain.commercelayer.io/api/braintree\\_gateways/:id>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches the braintree gateway identified by the ID "XAyRWNUzyN":

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a single resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "braintree_gateways",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN"
    },
    "attributes": {
      "name": "US payment gateway",
      "force_payments": true,
      "credential_keys": {
        "api_key": "********BW989"
      },
      "disabled_at": "2018-01-01T12:00:00.000Z",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      },
      "descriptor_name": "company*productabc1234",
      "descriptor_phone": "3125551212",
      "descriptor_url": "company.com",
      "webhook_endpoint_url": "https://core.commercelayer.co/webhook_callbacks/braintree_gateways/xxxxx"
    },
    "relationships": {
      "payment_methods": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/relationships/payment_methods",
          "related": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/payment_methods"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/event_stores"
        }
      },
      "braintree_payments": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/relationships/braintree_payments",
          "related": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/braintree_payments"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Update a braintree gateway

How to update an existing braintree gateway via API

To [update](https://docs.commercelayer.io/core/updating-resources) an existing braintree gateway, send a `PATCH` request to the `/api/braintree_gateways/:id` endpoint, where `id` is the ID of the resource that you want to update.

Here below the list of all the possible arguments that you can pass with the request body.

## Request

**PATCH** <https://yourdomain.commercelayer.io/api/braintree\\_gateways/:id>

### Arguments

| Body Parameter                        | Type      | Required |
| ------------------------------------- | --------- | -------- |
| **type**                              | `string`  | Required |
| **id**                                | `string`  | Required |
| attributes.**name**                   | `string`  | Optional |
| attributes.**force\_payments**        | `boolean` | Optional |
| attributes.**\_disable**              | `boolean` | Optional |
| attributes.**\_enable**               | `boolean` | Optional |
| attributes.**reference**              | `string`  | Optional |
| attributes.**reference\_origin**      | `string`  | Optional |
| attributes.**metadata**               | `object`  | Optional |
| attributes.**\_check**                | `boolean` | Optional |
| attributes.**merchant\_account\_id**  | `string`  | Optional |
| attributes.**merchant\_id**           | `string`  | Optional |
| attributes.**public\_key**            | `string`  | Optional |
| attributes.**private\_key**           | `string`  | Optional |
| attributes.**descriptor\_name**       | `string`  | Optional |
| attributes.**descriptor\_phone**      | `string`  | Optional |
| attributes.**descriptor\_url**        | `string`  | Optional |
| relationships.**braintree\_payments** | `array`   | Optional |

### Example

{% tabs %}
{% tab title="Request" %}
The following request updates the braintree gateway identified by the ID "XAyRWNUzyN":

```shell
curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "braintree_gateways",
    "id": "xYZkjABcde",
    "attributes": {
      "_disable": true
    },
    "relationships": {
      "braintree_payments": {
        "data": {
          "type": "braintree_payments",
          "id": "ABCRtyUpBa"
        }
      }
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the updated resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "braintree_gateways",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN"
    },
    "attributes": {
      "name": "US payment gateway",
      "force_payments": true,
      "credential_keys": {
        "api_key": "********BW989"
      },
      "disabled_at": "2018-01-01T12:00:00.000Z",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      },
      "descriptor_name": "company*productabc1234",
      "descriptor_phone": "3125551212",
      "descriptor_url": "company.com",
      "webhook_endpoint_url": "https://core.commercelayer.co/webhook_callbacks/braintree_gateways/xxxxx"
    },
    "relationships": {
      "payment_methods": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/relationships/payment_methods",
          "related": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/payment_methods"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/event_stores"
        }
      },
      "braintree_payments": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/relationships/braintree_payments",
          "related": "https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN/braintree_payments"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Delete a braintree gateway

How to delete an existing braintree gateway via API

To [delete](https://docs.commercelayer.io/core/deleting-resources) a braintree gateway, send a `DELETE` request to the `/api/braintree_gateways/:id` endpoint, where `id` is the id of the braintree gateway that you want to delete.

## Request

**DELETE** <https://yourdomain.commercelayer.io/api/braintree\\_gateways/:id>

### Example

{% tabs %}
{% tab title="Request" %}
The following request tries to delete the braintree gateway identified by the ID "XAyRWNUzyN":

```shell
curl -g -X DELETE \
  'https://yourdomain.commercelayer.io/api/braintree_gateways/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `204 No Content` status code.
{% endtab %}
{% endtabs %}


# Braintree payments

The Braintree payment object and the allowed CRUD operations on the related resource endpoint

Braintree payments are a type of payment source that lets you process payments through [Braintree gateways](/core-api-reference/braintree_gateways).


# The braintree payment object

A comprehensive list of the braintree payment resource's attributes and relationships

A braintree payment object is returned as part of the response body of each successful list, retrieve, create or update API call to the `/api/braintree_payments` endpoint.

## Fields

| Field                                 | Type      | Description                                                                                                                                                                                         |
| ------------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **type**                              | `string`  | `braintree_payments`                                                                                                                                                                                |
| **id**                                | `string`  | The braintree payment unique identifier                                                                                                                                                             |
| links.**self**                        | `string`  | The braintree payment endpoint URL                                                                                                                                                                  |
| attributes.**client\_token**          | `string`  | The Braintree payment client token. Required by the Braintree JS SDK.                                                                                                                               |
| attributes.**payment\_method\_nonce** | `string`  | The Braintree payment method nonce. Sent by the Braintree JS SDK.                                                                                                                                   |
| attributes.**payment\_id**            | `string`  | The Braintree payment ID used by local payment and sent by the Braintree JS SDK.                                                                                                                    |
| attributes.**local**                  | `boolean` | Indicates if the payment is local, in such case Braintree will trigger a webhook call passing the "payment\_id" and "payment\_method\_nonce" in order to complete the transaction.                  |
| attributes.**options**                | `object`  | Braintree payment options, 'customer\_id' and 'payment\_method\_token'.                                                                                                                             |
| attributes.**payment\_instrument**    | `object`  | Information about the payment instrument used in the transaction.                                                                                                                                   |
| attributes.**created\_at**            | `string`  | Time at which the resource was created.                                                                                                                                                             |
| attributes.**updated\_at**            | `string`  | Time at which the resource was last updated.                                                                                                                                                        |
| attributes.**reference**              | `string`  | A string that you can use to add any external identifier to the resource. This can be useful for integrating the resource to an external system, like an ERP, a marketing tool, a CRM, or whatever. |
| attributes.**reference\_origin**      | `string`  | Any identifier of the third party system that defines the reference code.                                                                                                                           |
| attributes.**metadata**               | `object`  | Set of key-value pairs that you can attach to the resource. This can be useful for storing additional information about the resource in a structured format.                                        |
| relationships.**order**               | `object`  | The order associated to the Braintree payment, that is set as its payment source.                                                                                                                   |
| relationships.**payment\_gateway**    | `object`  | The associated payment gateway, inherited by the order payment\_method.                                                                                                                             |
| relationships.**event\_stores**       | `array`   | The associated event stores.                                                                                                                                                                        |
| meta.**mode**                         | `string`  | The resource environment (can be one of `test` or `live`)                                                                                                                                           |


# Create a braintree payment

How to create a braintree payment via API

To [create](https://docs.commercelayer.io/core/creating-resources) a new braintree payment, send a `POST` request to the `/api/braintree_payments` endpoint, passing the resource arguments in the request body.

## Request

**POST** <https://yourdomain.commercelayer.io/api/braintree\\_payments>

### Arguments

| Body Parameter                   | Type      | Required |
| -------------------------------- | --------- | -------- |
| **type**                         | `string`  | Required |
| attributes.**payment\_id**       | `string`  | Optional |
| attributes.**local**             | `boolean` | Optional |
| attributes.**options**           | `object`  | Optional |
| attributes.**reference**         | `string`  | Optional |
| attributes.**reference\_origin** | `string`  | Optional |
| attributes.**metadata**          | `object`  | Optional |
| relationships.**order**          | `object`  | Required |

### Example

{% tabs %}
{% tab title="Request" %}
The following request creates a new braintree payment:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/braintree_payments' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "braintree_payments",
    "relationships": {
      "order": {
        "data": {
          "type": "orders",
          "id": "ABCRtyUpBa"
        }
      }
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "braintree_payments",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN"
    },
    "attributes": {
      "client_token": "xxxx.yyyy.zzzz",
      "payment_method_nonce": "xxxx.yyyy.zzzz",
      "payment_id": "xxxx.yyyy.zzzz",
      "local": true,
      "options": {
        "customer_id": "1234567890"
      },
      "payment_instrument": {
        "issuer": "cl bank",
        "card_type": "visa"
      },
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "order": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/relationships/order",
          "related": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/order"
        }
      },
      "payment_gateway": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/relationships/payment_gateway",
          "related": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/payment_gateway"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# List all braintree payments

How to fetch a collection of braintree payments via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a collection of braintree payments, send a `GET` request to the `/api/braintree_payments` endpoint.

## Request

**GET** <https://yourdomain.commercelayer.io/api/braintree\\_payments>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches a collection of braintree payments:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/braintree_payments/' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of resource objects:

```json
{
  "data": [
    {
      "id": "XAyRWNUzyN",
      "type": "braintree_payments",
      "links": {
        "self": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN"
      },
      "attributes": {
        "client_token": "xxxx.yyyy.zzzz",
        "payment_method_nonce": "xxxx.yyyy.zzzz",
        "payment_id": "xxxx.yyyy.zzzz",
        "local": true,
        "options": {
          "customer_id": "1234567890"
        },
        "payment_instrument": {
          "issuer": "cl bank",
          "card_type": "visa"
        },
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": "ANY-EXTERNAL-REFEFERNCE",
        "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
        "metadata": {
          "foo": "bar"
        }
      },
      "relationships": {
        "order": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/relationships/order",
            "related": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/order"
          }
        },
        "payment_gateway": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/relationships/payment_gateway",
            "related": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/payment_gateway"
          }
        },
        "event_stores": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/relationships/event_stores",
            "related": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/event_stores"
          }
        }
      },
      "meta": {
        "mode": "test",
        "organization_id": "xRRkjDFafe",
        "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
      }
    },
    {
      "other": "... 9 braintree_payments (first page)"
    }
  ],
  "meta": {
    "record_count": 140,
    "page_count": 14
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/braintree_payments?page[number]=1&page[size]=10",
    "next": "https://yourdomain.commercelayer.io/api/braintree_payments?page[number]=2&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/braintree_payments?page[number]=14&page[size]=10"
  }
}
```

{% endtab %}
{% endtabs %}

Remember that when you fetch a list of resources you get [paginated](https://docs.commercelayer.io/core/pagination) result.

### Sortable fields

The list of braintree payments can be [sorted](https://docs.commercelayer.io/core/sorting-results) by the following fields:

#### Attributes

* `id`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`

#### Relationships

* `order`

### Filterable fields

The list of braintree payments can be [filtered](https://docs.commercelayer.io/core/filtering-data) by the following fields:

#### Attributes

* `id`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`
* `metadata`

#### Relationships

* `order`


# Retrieve a braintree payment

How to fetch a specific braintree payment via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a single braintree payment, send a `GET` request to the `/api/braintree_payments/:id` endpoint, where `id` is the ID of the resource that you want to retrieve.

## Request

**GET** <https://yourdomain.commercelayer.io/api/braintree\\_payments/:id>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches the braintree payment identified by the ID "XAyRWNUzyN":

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a single resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "braintree_payments",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN"
    },
    "attributes": {
      "client_token": "xxxx.yyyy.zzzz",
      "payment_method_nonce": "xxxx.yyyy.zzzz",
      "payment_id": "xxxx.yyyy.zzzz",
      "local": true,
      "options": {
        "customer_id": "1234567890"
      },
      "payment_instrument": {
        "issuer": "cl bank",
        "card_type": "visa"
      },
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "order": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/relationships/order",
          "related": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/order"
        }
      },
      "payment_gateway": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/relationships/payment_gateway",
          "related": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/payment_gateway"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Update a braintree payment

How to update an existing braintree payment via API

To [update](https://docs.commercelayer.io/core/updating-resources) an existing braintree payment, send a `PATCH` request to the `/api/braintree_payments/:id` endpoint, where `id` is the ID of the resource that you want to update.

Here below the list of all the possible arguments that you can pass with the request body.

## Request

**PATCH** <https://yourdomain.commercelayer.io/api/braintree\\_payments/:id>

### Arguments

| Body Parameter                        | Type      | Required |
| ------------------------------------- | --------- | -------- |
| **type**                              | `string`  | Required |
| **id**                                | `string`  | Required |
| attributes.**payment\_method\_nonce** | `string`  | Optional |
| attributes.**payment\_id**            | `string`  | Optional |
| attributes.**local**                  | `boolean` | Optional |
| attributes.**options**                | `object`  | Optional |
| attributes.**reference**              | `string`  | Optional |
| attributes.**reference\_origin**      | `string`  | Optional |
| attributes.**metadata**               | `object`  | Optional |
| relationships.**order**               | `object`  | Optional |

### Example

{% tabs %}
{% tab title="Request" %}
The following request updates the braintree payment identified by the ID "XAyRWNUzyN":

```shell
curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "braintree_payments",
    "id": "xYZkjABcde",
    "attributes": {
      "payment_method_nonce": "xxxx.yyyy.zzzz"
    },
    "relationships": {
      "order": {
        "data": {
          "type": "orders",
          "id": "ABCRtyUpBa"
        }
      }
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the updated resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "braintree_payments",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN"
    },
    "attributes": {
      "client_token": "xxxx.yyyy.zzzz",
      "payment_method_nonce": "xxxx.yyyy.zzzz",
      "payment_id": "xxxx.yyyy.zzzz",
      "local": true,
      "options": {
        "customer_id": "1234567890"
      },
      "payment_instrument": {
        "issuer": "cl bank",
        "card_type": "visa"
      },
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "order": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/relationships/order",
          "related": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/order"
        }
      },
      "payment_gateway": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/relationships/payment_gateway",
          "related": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/payment_gateway"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Delete a braintree payment

How to delete an existing braintree payment via API

To [delete](https://docs.commercelayer.io/core/deleting-resources) a braintree payment, send a `DELETE` request to the `/api/braintree_payments/:id` endpoint, where `id` is the id of the braintree payment that you want to delete.

## Request

**DELETE** <https://yourdomain.commercelayer.io/api/braintree\\_payments/:id>

### Example

{% tabs %}
{% tab title="Request" %}
The following request tries to delete the braintree payment identified by the ID "XAyRWNUzyN":

```shell
curl -g -X DELETE \
  'https://yourdomain.commercelayer.io/api/braintree_payments/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `204 No Content` status code.
{% endtab %}
{% endtabs %}


# Bundles

The bundle object and the allowed CRUD operations on the related resource endpoint

Bundles describe a set of specific products that are being sold. A unique code identifies each bundle. The bundle name, description, and image URL are best suited for internal usage (Commerce Layer is not a CMS). Bundles are linked to manual SKU lists, inheriting the SKUs from there.

{% hint style="info" %}
A **maximum of 10 SKU list items** are permitted for each bundle. Once an SKU list is associated with a bundle, its items cannot be added, removed, or updated, unless you first destroy all of the linked bundles.
{% endhint %}

Bundles have `price_amount_cents` and `compare_at_amount_cents` attributes: the latter can be specified or computed as the sum of the SKUs, but is always guaranteed to be smaller than or equal to the former. Once a price is assigned to a bundle, the currency is inherited by the relationship with the associated active market. If that relationship is not specified, a currency must be assigned to the bundle.

{% hint style="warning" %}
When passing the `_compute_price_amount` and `_compute_compare_at_amount` trigger attributes the relationship with a specific market must be set, otherwise the API will return an error.
{% endhint %}

<details>

<summary>Data model</summary>

Check the related [ER diagram](https://commercelayer.io/docs/data-model/bundles) and explore the flowchart that illustrates how the bundle resource relates to the other API entities.

</details>


# The bundle object

A comprehensive list of the bundle resource's attributes and relationships

A bundle object is returned as part of the response body of each successful list, retrieve, create or update API call to the `/api/bundles` endpoint.

## Fields

| Field                                         | Type      | Description                                                                                                                                                                                         |
| --------------------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **type**                                      | `string`  | `bundles`                                                                                                                                                                                           |
| **id**                                        | `string`  | The bundle unique identifier                                                                                                                                                                        |
| links.**self**                                | `string`  | The bundle endpoint URL                                                                                                                                                                             |
| attributes.**code**                           | `string`  | The bundle code, that uniquely identifies the bundle within the market.                                                                                                                             |
| attributes.**name**                           | `string`  | The internal name of the bundle.                                                                                                                                                                    |
| attributes.**currency\_code**                 | `string`  | The international 3-letter currency code as defined by the ISO 4217 standard.                                                                                                                       |
| attributes.**description**                    | `string`  | An internal description of the bundle.                                                                                                                                                              |
| attributes.**image\_url**                     | `string`  | The URL of an image that represents the bundle.                                                                                                                                                     |
| attributes.**do\_not\_ship**                  | `boolean` | Indicates if the bundle doesn't generate shipments (all sku\_list's SKUs must be do\_not\_ship).                                                                                                    |
| attributes.**do\_not\_track**                 | `boolean` | Indicates if the bundle doesn't track the stock inventory (all sku\_list's SKUs must be do\_not\_track).                                                                                            |
| attributes.**price\_amount\_cents**           | `integer` | The bundle price amount for the associated market, in cents.                                                                                                                                        |
| attributes.**price\_amount\_float**           | `float`   | The bundle price amount for the associated market, float.                                                                                                                                           |
| attributes.**formatted\_price\_amount**       | `string`  | The bundle price amount for the associated market, formatted.                                                                                                                                       |
| attributes.**compare\_at\_amount\_cents**     | `integer` | The compared price amount, in cents. Useful to display a percentage discount.                                                                                                                       |
| attributes.**compare\_at\_amount\_float**     | `float`   | The compared price amount, float.                                                                                                                                                                   |
| attributes.**formatted\_compare\_at\_amount** | `string`  | The compared price amount, formatted.                                                                                                                                                               |
| attributes.**\_compute\_price\_amount**       | `boolean` | Send this attribute if you want to compute the price\_amount\_cents as the sum of the prices of the bundle SKUs for the market.                                                                     |
| attributes.**\_compute\_compare\_at\_amount** | `boolean` | Send this attribute if you want to compute the compare\_at\_amount\_cents as the sum of the prices of the bundle SKUs for the market.                                                               |
| attributes.**skus\_count**                    | `integer` | The total number of SKUs in the bundle.                                                                                                                                                             |
| attributes.**\_add\_tags**                    | `string`  | Comma separated list of tags to be added. Duplicates, invalid and non existing ones are discarded. Cannot be passed by sales channels.                                                              |
| attributes.**\_remove\_tags**                 | `string`  | Comma separated list of tags to be removed. Duplicates, invalid and non existing ones are discarded. Cannot be passed by sales channels.                                                            |
| attributes.**created\_at**                    | `string`  | Time at which the resource was created.                                                                                                                                                             |
| attributes.**updated\_at**                    | `string`  | Time at which the resource was last updated.                                                                                                                                                        |
| attributes.**reference**                      | `string`  | A string that you can use to add any external identifier to the resource. This can be useful for integrating the resource to an external system, like an ERP, a marketing tool, a CRM, or whatever. |
| attributes.**reference\_origin**              | `string`  | Any identifier of the third party system that defines the reference code.                                                                                                                           |
| attributes.**metadata**                       | `object`  | Set of key-value pairs that you can attach to the resource. This can be useful for storing additional information about the resource in a structured format.                                        |
| relationships.**market**                      | `object`  | The associated market.                                                                                                                                                                              |
| relationships.**sku\_list**                   | `object`  | The associated SKU list.                                                                                                                                                                            |
| relationships.**skus**                        | `array`   | The associated SKUs.                                                                                                                                                                                |
| relationships.**attachments**                 | `array`   | The associated attachments.                                                                                                                                                                         |
| relationships.**events**                      | `array`   | The associated events.                                                                                                                                                                              |
| relationships.**tags**                        | `array`   | The associated tags. Cannot be passed by sales channels.                                                                                                                                            |
| relationships.**event\_stores**               | `array`   | The associated event stores.                                                                                                                                                                        |
| meta.**mode**                                 | `string`  | The resource environment (can be one of `test` or `live`)                                                                                                                                           |


# Create a bundle

How to create a bundle via API

To [create](https://docs.commercelayer.io/core/creating-resources) a new bundle, send a `POST` request to the `/api/bundles` endpoint, passing the resource arguments in the request body.

## Request

**POST** <https://yourdomain.commercelayer.io/api/bundles>

### Arguments

| Body Parameter                                | Type      | Required                             |
| --------------------------------------------- | --------- | ------------------------------------ |
| **type**                                      | `string`  | Required                             |
| attributes.**code**                           | `string`  | Required                             |
| attributes.**name**                           | `string`  | Required                             |
| attributes.**currency\_code**                 | `string`  | Required, unless inherited by market |
| attributes.**description**                    | `string`  | Optional                             |
| attributes.**image\_url**                     | `string`  | Optional                             |
| attributes.**price\_amount\_cents**           | `integer` | Required, unless computed            |
| attributes.**compare\_at\_amount\_cents**     | `integer` | Optional                             |
| attributes.**\_compute\_price\_amount**       | `boolean` | Optional                             |
| attributes.**\_compute\_compare\_at\_amount** | `boolean` | Optional                             |
| attributes.**reference**                      | `string`  | Optional                             |
| attributes.**reference\_origin**              | `string`  | Optional                             |
| attributes.**metadata**                       | `object`  | Optional                             |
| relationships.**market**                      | `object`  | Optional                             |
| relationships.**sku\_list**                   | `object`  | Required                             |
| relationships.**tags**                        | `array`   | Optional                             |

### Example

{% tabs %}
{% tab title="Request" %}
The following request creates a new bundle:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/bundles' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "bundles",
    "attributes": {
      "code": "BUNDMM000000FFFFFFXLXX",
      "name": "Men's Black T-shirt (XL) with Black Cap and Socks, all with White Logo",
      "currency_code": "EUR",
      "price_amount_cents": 10000
    },
    "relationships": {
      "sku_list": {
        "data": {
          "type": "sku_lists",
          "id": "ABCRtyUpBa"
        }
      }
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "bundles",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN"
    },
    "attributes": {
      "code": "BUNDMM000000FFFFFFXLXX",
      "name": "Men's Black T-shirt (XL) with Black Cap and Socks, all with White Logo",
      "currency_code": "EUR",
      "description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
      "image_url": "https://img.yourdomain.com/bundles/xYZkjABcde.png",
      "do_not_ship": false,
      "do_not_track": false,
      "price_amount_cents": 10000,
      "price_amount_float": 100.0,
      "formatted_price_amount": "€100,00",
      "compare_at_amount_cents": 13000,
      "compare_at_amount_float": 130.0,
      "formatted_compare_at_amount": "€130,00",
      "skus_count": 2,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "market": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/market",
          "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/market"
        }
      },
      "sku_list": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/sku_list",
          "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/sku_list"
        }
      },
      "skus": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/skus",
          "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/skus"
        }
      },
      "attachments": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/attachments",
          "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/attachments"
        }
      },
      "events": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/events",
          "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/events"
        }
      },
      "tags": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/tags",
          "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/tags"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# List all bundles

How to fetch a collection of bundles via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a collection of bundles, send a `GET` request to the `/api/bundles` endpoint.

## Request

**GET** <https://yourdomain.commercelayer.io/api/bundles>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches a collection of bundles:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/bundles/' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of resource objects:

```json
{
  "data": [
    {
      "id": "XAyRWNUzyN",
      "type": "bundles",
      "links": {
        "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN"
      },
      "attributes": {
        "code": "BUNDMM000000FFFFFFXLXX",
        "name": "Men's Black T-shirt (XL) with Black Cap and Socks, all with White Logo",
        "currency_code": "EUR",
        "description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        "image_url": "https://img.yourdomain.com/bundles/xYZkjABcde.png",
        "do_not_ship": false,
        "do_not_track": false,
        "price_amount_cents": 10000,
        "price_amount_float": 100.0,
        "formatted_price_amount": "€100,00",
        "compare_at_amount_cents": 13000,
        "compare_at_amount_float": 130.0,
        "formatted_compare_at_amount": "€130,00",
        "skus_count": 2,
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": "ANY-EXTERNAL-REFEFERNCE",
        "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
        "metadata": {
          "foo": "bar"
        }
      },
      "relationships": {
        "market": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/market",
            "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/market"
          }
        },
        "sku_list": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/sku_list",
            "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/sku_list"
          }
        },
        "skus": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/skus",
            "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/skus"
          }
        },
        "attachments": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/attachments",
            "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/attachments"
          }
        },
        "events": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/events",
            "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/events"
          }
        },
        "tags": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/tags",
            "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/tags"
          }
        },
        "event_stores": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/event_stores",
            "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/event_stores"
          }
        }
      },
      "meta": {
        "mode": "test",
        "organization_id": "xRRkjDFafe",
        "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
      }
    },
    {
      "other": "... 9 bundles (first page)"
    }
  ],
  "meta": {
    "record_count": 140,
    "page_count": 14
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/bundles?page[number]=1&page[size]=10",
    "next": "https://yourdomain.commercelayer.io/api/bundles?page[number]=2&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/bundles?page[number]=14&page[size]=10"
  }
}
```

{% endtab %}
{% endtabs %}

Remember that when you fetch a list of resources you get [paginated](https://docs.commercelayer.io/core/pagination) result.

### Sortable fields

The list of bundles can be [sorted](https://docs.commercelayer.io/core/sorting-results) by the following fields:

#### Attributes

* `code`
* `name`
* `currency_code`
* `price_amount_cents`
* `compare_at_amount_cents`
* `id`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`

#### Relationships

* `market`
* `sku_list`

### Filterable fields

The list of bundles can be [filtered](https://docs.commercelayer.io/core/filtering-data) by the following fields:

#### Attributes

* `code`
* `name`
* `currency_code`
* `description`
* `image_url`
* `do_not_ship`
* `do_not_track`
* `price_amount_cents`
* `compare_at_amount_cents`
* `id`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`
* `metadata`

#### Relationships

* `market`
* `sku_list`
* `attachments`
* `events`
* `tags`


# Retrieve a bundle

How to fetch a specific bundle via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a single bundle, send a `GET` request to the `/api/bundles/:id` endpoint, where `id` is the ID of the resource that you want to retrieve.

## Request

**GET** <https://yourdomain.commercelayer.io/api/bundles/:id>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches the bundle identified by the ID "XAyRWNUzyN":

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a single resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "bundles",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN"
    },
    "attributes": {
      "code": "BUNDMM000000FFFFFFXLXX",
      "name": "Men's Black T-shirt (XL) with Black Cap and Socks, all with White Logo",
      "currency_code": "EUR",
      "description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
      "image_url": "https://img.yourdomain.com/bundles/xYZkjABcde.png",
      "do_not_ship": false,
      "do_not_track": false,
      "price_amount_cents": 10000,
      "price_amount_float": 100.0,
      "formatted_price_amount": "€100,00",
      "compare_at_amount_cents": 13000,
      "compare_at_amount_float": 130.0,
      "formatted_compare_at_amount": "€130,00",
      "skus_count": 2,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "market": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/market",
          "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/market"
        }
      },
      "sku_list": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/sku_list",
          "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/sku_list"
        }
      },
      "skus": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/skus",
          "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/skus"
        }
      },
      "attachments": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/attachments",
          "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/attachments"
        }
      },
      "events": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/events",
          "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/events"
        }
      },
      "tags": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/tags",
          "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/tags"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Update a bundle

How to update an existing bundle via API

To [update](https://docs.commercelayer.io/core/updating-resources) an existing bundle, send a `PATCH` request to the `/api/bundles/:id` endpoint, where `id` is the ID of the resource that you want to update.

Here below the list of all the possible arguments that you can pass with the request body.

## Request

**PATCH** <https://yourdomain.commercelayer.io/api/bundles/:id>

### Arguments

| Body Parameter                                | Type      | Required |
| --------------------------------------------- | --------- | -------- |
| **type**                                      | `string`  | Required |
| **id**                                        | `string`  | Required |
| attributes.**code**                           | `string`  | Optional |
| attributes.**name**                           | `string`  | Optional |
| attributes.**currency\_code**                 | `string`  | Optional |
| attributes.**description**                    | `string`  | Optional |
| attributes.**image\_url**                     | `string`  | Optional |
| attributes.**price\_amount\_cents**           | `integer` | Optional |
| attributes.**compare\_at\_amount\_cents**     | `integer` | Optional |
| attributes.**\_compute\_price\_amount**       | `boolean` | Optional |
| attributes.**\_compute\_compare\_at\_amount** | `boolean` | Optional |
| attributes.**\_add\_tags**                    | `string`  | Optional |
| attributes.**\_remove\_tags**                 | `string`  | Optional |
| attributes.**reference**                      | `string`  | Optional |
| attributes.**reference\_origin**              | `string`  | Optional |
| attributes.**metadata**                       | `object`  | Optional |
| relationships.**tags**                        | `array`   | Optional |

### Example

{% tabs %}
{% tab title="Request" %}
The following request updates the bundle identified by the ID "XAyRWNUzyN":

```shell
curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "bundles",
    "id": "xYZkjABcde",
    "attributes": {
      "description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
    },
    "relationships": {
      "tags": {
        "data": {
          "type": "tags",
          "id": "ABCRtyUpBa"
        }
      }
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the updated resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "bundles",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN"
    },
    "attributes": {
      "code": "BUNDMM000000FFFFFFXLXX",
      "name": "Men's Black T-shirt (XL) with Black Cap and Socks, all with White Logo",
      "currency_code": "EUR",
      "description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
      "image_url": "https://img.yourdomain.com/bundles/xYZkjABcde.png",
      "do_not_ship": false,
      "do_not_track": false,
      "price_amount_cents": 10000,
      "price_amount_float": 100.0,
      "formatted_price_amount": "€100,00",
      "compare_at_amount_cents": 13000,
      "compare_at_amount_float": 130.0,
      "formatted_compare_at_amount": "€130,00",
      "skus_count": 2,
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      }
    },
    "relationships": {
      "market": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/market",
          "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/market"
        }
      },
      "sku_list": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/sku_list",
          "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/sku_list"
        }
      },
      "skus": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/skus",
          "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/skus"
        }
      },
      "attachments": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/attachments",
          "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/attachments"
        }
      },
      "events": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/events",
          "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/events"
        }
      },
      "tags": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/tags",
          "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/tags"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN/event_stores"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Delete a bundle

How to delete an existing bundle via API

To [delete](https://docs.commercelayer.io/core/deleting-resources) a bundle, send a `DELETE` request to the `/api/bundles/:id` endpoint, where `id` is the id of the bundle that you want to delete.

## Request

**DELETE** <https://yourdomain.commercelayer.io/api/bundles/:id>

### Example

{% tabs %}
{% tab title="Request" %}
The following request tries to delete the bundle identified by the ID "XAyRWNUzyN":

```shell
curl -g -X DELETE \
  'https://yourdomain.commercelayer.io/api/bundles/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `204 No Content` status code.
{% endtab %}
{% endtabs %}


# Buy x pay y promotions

The buy X pay Y promotion object and the allowed CRUD operations on the related resource endpoint

Commerce Layer provides a promotional engine built on top of two main resources: [promotions](/core-api-reference/promotions) and [promotion rules](/core-api-reference/promotion_rules).

When triggered, buy X pay Y promotions are responsible for adding a discount to the orders involved. The related discount amount is computed based on the associated SKU list: for each SKU in the order that belongs to the list and has a quantity equal to any multiple of the `x` attribute, a discount is applied as if the purchased quantity of the same SKU was decreased down to the same multiple of the `y` attribute. Basically, customers that add to cart a number greater than or equal to `n*x` (and less than `(n+1)*x`) units of a specific product pay only for `n*y` units of the same product, thus getting `n*(x-y)` units for free — where `x` must be greater than `y` (and `n` greater than zero). The corresponding stock is updated consistently (i.e. decreased by `n*x` units).

{% hint style="info" %}
In order for buy X pay Y promotions to apply to [bundles](/core-api-reference/bundles), the resources must share the same [SKU list](/core-api-reference/sku_lists) (in this case, there is no SKUs partial matching).
{% endhint %}

Let's consider an example where a buy X pay Y promotion (with **X=3** and **Y=2**) is associated with an SKU list containing the products A, B, and C. Some of the possible scenarios are the following:

* If customers add to cart **3** units of product A, they pay for **2** and get **1** of them for free.
* If customers add to cart **6** units of product A and **3** units of product B, they get **2** units of product A and **1** unit of product B for free.
* If customers add to cart **7** units of product A, **4** units of product B, and **2** units of product C, they get **2** units of product A and **1** unit of product B for free.
* If customers add to cart **5** units of product A, **2** units of product B, and **8** units of product D (which is not in the associated SKU list), they get **1** unit of product A for free.
* If customers add to cart **2** units of product A and **4** units of product D (which is not in the associated SKU list), the promotion doesn't apply and they get no discount.

## Cheapest free

If you set the `cheapest_free` attribute to `true` (default is `false`) the buy X pay Y promotion type behaves differently. In this case, the value of the `x` attribute is matched against the sum of the quantities of *all* the SKUs in the associated list. If the order contains some of the SKU belonging to the list and the sum of their quantity is equal to any multiple of `x` (i.e. `n*x`), the customer will pay only for the most expensive `n*y`, thus getting the `n*(x-y)` cheapest ones among those SKUs for free.

Considering the same example as above in the case of a *cheapest free* buy X pay Y promotion (let's assume that A is the most expensive and C the cheapest of the three products), the aforementioned scenarios could now lead to different discounts:

* If customers add to cart **3** units of product A, they pay for **2** and get **1** of them for free.
* If customers add to cart **6** units of product A and **3** units of product B (**9** units of products belonging to the list in total), they get all **3** units of product B for free.
* If customers add to cart **7** units of product A, **4** units of product B, and **2** units of product C (**13** units of products belonging to the list in total), they get **2** units of product B and all **2** units of product C for free (**4** units for free in total).
* If customers add to cart **5** units of product A, **2** units of product B, and **8** units of product D (**7** units of products belonging to the list in total), they get all **2** the units of the product B for free.
* If customers add to cart **2** units of product A and **4** units of product D (**2** units of products belonging to the list in total), the promotion doesn't apply and they get no discount.

## Application scope

Buy X pay Y promotions can be optionally defined by currency code or restricted to a specific active market (in the latter case the currency code is inherited by the market's price list). Within the time window given by their activation and expiration dates, buy X pay Y promotions that have not reached their total usage limit are considered active. If no promotion rule is associated with an active buy X pay Y promotion, the discount is applied to:

* All the orders, if the promotion is not restricted to a specific currency or market.
* All the orders in the specified currency, if a currency code is specified but the promotion is not restricted to a specific market.
* All the orders of the market in scope, if the promotion is attached to a market.

Otherwise, if one or more promotion rules are defined, the promotion is triggered only when it matches all of them.

{% hint style="info" %}
Multiple buy X pay Y promotions can be applied to the same order, even concurrently with other promotion types (based on their [priority](/core-api-reference/promotions#priority-and-order-of-application) and up to the involved items amount [saturation](/core-api-reference/promotions#discount-distribution)), as long as you don't reach the maximum number of active promotions allowed for your organization.
{% endhint %}

## Discount calculation and distribution

The total discount due to buy X pay Y promotions is calculated and distributed on the matching line items of type `skus` or `bundles` belonging to the associated SKU list, according to the promotion logic.


# The buy x pay y promotion object

A comprehensive list of the buy x pay y promotion resource's attributes and relationships

A buy x pay y promotion object is returned as part of the response body of each successful list, retrieve, create or update API call to the `/api/buy_x_pay_y_promotions` endpoint.

## Fields

| Field                                            | Type      | Description                                                                                                                                                                                         |
| ------------------------------------------------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **type**                                         | `string`  | `buy_x_pay_y_promotions`                                                                                                                                                                            |
| **id**                                           | `string`  | The buy x pay y promotion unique identifier                                                                                                                                                         |
| links.**self**                                   | `string`  | The buy x pay y promotion endpoint URL                                                                                                                                                              |
| attributes.**name**                              | `string`  | The promotion's internal name.                                                                                                                                                                      |
| attributes.**currency\_code**                    | `string`  | The international 3-letter currency code as defined by the ISO 4217 standard.                                                                                                                       |
| attributes.**exclusive**                         | `boolean` | Indicates if the promotion will be applied exclusively, based on its priority score.                                                                                                                |
| attributes.**priority**                          | `integer` | The priority assigned to the promotion (lower means higher priority).                                                                                                                               |
| attributes.**starts\_at**                        | `string`  | The activation date/time of this promotion.                                                                                                                                                         |
| attributes.**expires\_at**                       | `string`  | The expiration date/time of this promotion (must be after starts\_at).                                                                                                                              |
| attributes.**total\_usage\_limit**               | `integer` | The total number of times this promotion can be applied. When 'null' it means promotion can be applied infinite times.                                                                              |
| attributes.**total\_usage\_count**               | `integer` | The number of times this promotion has been applied.                                                                                                                                                |
| attributes.**total\_usage\_reached**             | `boolean` | Indicates if the promotion has been applied the total number of allowed times.                                                                                                                      |
| attributes.**active**                            | `boolean` | Indicates if the promotion is active (enabled and not expired).                                                                                                                                     |
| attributes.**status**                            | `string`  | The promotion status. One of 'disabled', 'expired', 'pending', 'active', or 'inactive'.                                                                                                             |
| attributes.**weight**                            | `integer` | The weight of the promotion, computed by exclusivity, priority, type and start time. Determines the order of application, higher weight apply first.                                                |
| attributes.**coupons\_count**                    | `integer` | The total number of coupons created for this promotion.                                                                                                                                             |
| attributes.**\_disable**                         | `boolean` | Send this attribute if you want to mark this resource as disabled.                                                                                                                                  |
| attributes.**\_enable**                          | `boolean` | Send this attribute if you want to mark this resource as enabled.                                                                                                                                   |
| attributes.**disabled\_at**                      | `string`  | Time at which this resource was disabled.                                                                                                                                                           |
| attributes.**\_add\_tags**                       | `string`  | Comma separated list of tags to be added. Duplicates, invalid and non existing ones are discarded. Cannot be passed by sales channels.                                                              |
| attributes.**\_remove\_tags**                    | `string`  | Comma separated list of tags to be removed. Duplicates, invalid and non existing ones are discarded. Cannot be passed by sales channels.                                                            |
| attributes.**created\_at**                       | `string`  | Time at which the resource was created.                                                                                                                                                             |
| attributes.**updated\_at**                       | `string`  | Time at which the resource was last updated.                                                                                                                                                        |
| attributes.**reference**                         | `string`  | A string that you can use to add any external identifier to the resource. This can be useful for integrating the resource to an external system, like an ERP, a marketing tool, a CRM, or whatever. |
| attributes.**reference\_origin**                 | `string`  | Any identifier of the third party system that defines the reference code.                                                                                                                           |
| attributes.**metadata**                          | `object`  | Set of key-value pairs that you can attach to the resource. This can be useful for storing additional information about the resource in a structured format.                                        |
| attributes.**x**                                 | `integer` | The quantity which defines the threshold for free items (works by multiple of x).                                                                                                                   |
| attributes.**y**                                 | `integer` | The quantity which defines how many items you get for free, with the formula x-y.                                                                                                                   |
| attributes.**cheapest\_free**                    | `boolean` | Indicates if the cheapest items are discounted, allowing all of the SKUs in the associated list to be eligible for counting.                                                                        |
| relationships.**market**                         | `object`  | The associated market.                                                                                                                                                                              |
| relationships.**promotion\_rules**               | `array`   | The associated promotion rules.                                                                                                                                                                     |
| relationships.**order\_amount\_promotion\_rule** | `object`  | The associated order amount promotion rule.                                                                                                                                                         |
| relationships.**sku\_list\_promotion\_rule**     | `object`  | The associated SKU list promotion rule.                                                                                                                                                             |
| relationships.**coupon\_codes\_promotion\_rule** | `object`  | The associated coupon codes promotion rule.                                                                                                                                                         |
| relationships.**custom\_promotion\_rule**        | `object`  | The associated custom promotion rule.                                                                                                                                                               |
| relationships.**sku\_list**                      | `object`  | The associated SKU list.                                                                                                                                                                            |
| relationships.**coupons**                        | `array`   | The associated coupons through coupon codes promotion rule.                                                                                                                                         |
| relationships.**attachments**                    | `array`   | The associated attachments.                                                                                                                                                                         |
| relationships.**events**                         | `array`   | The associated events.                                                                                                                                                                              |
| relationships.**tags**                           | `array`   | The associated tags. Cannot be passed by sales channels.                                                                                                                                            |
| relationships.**event\_stores**                  | `array`   | The associated event stores.                                                                                                                                                                        |
| relationships.**skus**                           | `array`   | The associated SKUs.                                                                                                                                                                                |
| meta.**mode**                                    | `string`  | The resource environment (can be one of `test` or `live`)                                                                                                                                           |


# Create a buy x pay y promotion

How to create a buy x pay y promotion via API

To [create](https://docs.commercelayer.io/core/creating-resources) a new buy x pay y promotion, send a `POST` request to the `/api/buy_x_pay_y_promotions` endpoint, passing the resource arguments in the request body.

## Request

**POST** <https://yourdomain.commercelayer.io/api/buy\\_x\\_pay\\_y\\_promotions>

### Arguments

| Body Parameter                                   | Type      | Required                     |
| ------------------------------------------------ | --------- | ---------------------------- |
| **type**                                         | `string`  | Required                     |
| attributes.**name**                              | `string`  | Required                     |
| attributes.**currency\_code**                    | `string`  | Optional                     |
| attributes.**exclusive**                         | `boolean` | Optional                     |
| attributes.**priority**                          | `integer` | Optional                     |
| attributes.**starts\_at**                        | `string`  | Required                     |
| attributes.**expires\_at**                       | `string`  | Required                     |
| attributes.**total\_usage\_limit**               | `integer` | Optional                     |
| attributes.**\_disable**                         | `boolean` | Optional                     |
| attributes.**\_enable**                          | `boolean` | Optional                     |
| attributes.**reference**                         | `string`  | Optional                     |
| attributes.**reference\_origin**                 | `string`  | Optional                     |
| attributes.**metadata**                          | `object`  | Optional                     |
| attributes.**x**                                 | `integer` | Required                     |
| attributes.**y**                                 | `integer` | Required                     |
| attributes.**cheapest\_free**                    | `boolean` | Optional, default is 'false' |
| relationships.**market**                         | `object`  | Optional                     |
| relationships.**order\_amount\_promotion\_rule** | `object`  | Optional                     |
| relationships.**sku\_list\_promotion\_rule**     | `object`  | Optional                     |
| relationships.**coupon\_codes\_promotion\_rule** | `object`  | Optional                     |
| relationships.**custom\_promotion\_rule**        | `object`  | Optional                     |
| relationships.**sku\_list**                      | `object`  | Required                     |
| relationships.**tags**                           | `array`   | Optional                     |

### Example

{% tabs %}
{% tab title="Request" %}
The following request creates a new buy x pay y promotion:

```shell
curl -g -X POST \
  'https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "buy_x_pay_y_promotions",
    "attributes": {
      "name": "Personal promotion",
      "starts_at": "2018-01-01T12:00:00.000Z",
      "expires_at": "2018-01-02T12:00:00.000Z",
      "x": 3,
      "y": 2
    },
    "relationships": {
      "sku_list": {
        "data": {
          "type": "sku_lists",
          "id": "ABCRtyUpBa"
        }
      }
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `201 Created` status code, returning the created resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "buy_x_pay_y_promotions",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN"
    },
    "attributes": {
      "name": "Personal promotion",
      "type": "percentage_discount_promotions",
      "currency_code": "EUR",
      "exclusive": true,
      "priority": 2,
      "starts_at": "2018-01-01T12:00:00.000Z",
      "expires_at": "2018-01-02T12:00:00.000Z",
      "total_usage_limit": 5,
      "total_usage_count": 2,
      "total_usage_reached": false,
      "active": true,
      "status": "pending",
      "weight": 112,
      "coupons_count": 2,
      "disabled_at": "2018-01-01T12:00:00.000Z",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      },
      "x": 3,
      "y": 2,
      "cheapest_free": true
    },
    "relationships": {
      "market": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/market",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/market"
        }
      },
      "promotion_rules": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/promotion_rules",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/promotion_rules"
        }
      },
      "order_amount_promotion_rule": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/order_amount_promotion_rule",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/order_amount_promotion_rule"
        }
      },
      "sku_list_promotion_rule": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/sku_list_promotion_rule",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/sku_list_promotion_rule"
        }
      },
      "coupon_codes_promotion_rule": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/coupon_codes_promotion_rule",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/coupon_codes_promotion_rule"
        }
      },
      "custom_promotion_rule": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/custom_promotion_rule",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/custom_promotion_rule"
        }
      },
      "sku_list": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/sku_list",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/sku_list"
        }
      },
      "coupons": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/coupons",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/coupons"
        }
      },
      "attachments": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/attachments",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/attachments"
        }
      },
      "events": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/events",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/events"
        }
      },
      "tags": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/tags",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/tags"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/event_stores"
        }
      },
      "skus": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/skus",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/skus"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# List all buy x pay y promotions

How to fetch a collection of buy x pay y promotions via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a collection of buy x pay y promotions, send a `GET` request to the `/api/buy_x_pay_y_promotions` endpoint.

## Request

**GET** <https://yourdomain.commercelayer.io/api/buy\\_x\\_pay\\_y\\_promotions>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches a collection of buy x pay y promotions:

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a paginated collection of resource objects:

```json
{
  "data": [
    {
      "id": "XAyRWNUzyN",
      "type": "buy_x_pay_y_promotions",
      "links": {
        "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN"
      },
      "attributes": {
        "name": "Personal promotion",
        "type": "percentage_discount_promotions",
        "currency_code": "EUR",
        "exclusive": true,
        "priority": 2,
        "starts_at": "2018-01-01T12:00:00.000Z",
        "expires_at": "2018-01-02T12:00:00.000Z",
        "total_usage_limit": 5,
        "total_usage_count": 2,
        "total_usage_reached": false,
        "active": true,
        "status": "pending",
        "weight": 112,
        "coupons_count": 2,
        "disabled_at": "2018-01-01T12:00:00.000Z",
        "created_at": "2018-01-01T12:00:00.000Z",
        "updated_at": "2018-01-01T12:00:00.000Z",
        "reference": "ANY-EXTERNAL-REFEFERNCE",
        "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
        "metadata": {
          "foo": "bar"
        },
        "x": 3,
        "y": 2,
        "cheapest_free": true
      },
      "relationships": {
        "market": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/market",
            "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/market"
          }
        },
        "promotion_rules": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/promotion_rules",
            "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/promotion_rules"
          }
        },
        "order_amount_promotion_rule": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/order_amount_promotion_rule",
            "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/order_amount_promotion_rule"
          }
        },
        "sku_list_promotion_rule": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/sku_list_promotion_rule",
            "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/sku_list_promotion_rule"
          }
        },
        "coupon_codes_promotion_rule": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/coupon_codes_promotion_rule",
            "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/coupon_codes_promotion_rule"
          }
        },
        "custom_promotion_rule": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/custom_promotion_rule",
            "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/custom_promotion_rule"
          }
        },
        "sku_list": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/sku_list",
            "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/sku_list"
          }
        },
        "coupons": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/coupons",
            "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/coupons"
          }
        },
        "attachments": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/attachments",
            "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/attachments"
          }
        },
        "events": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/events",
            "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/events"
          }
        },
        "tags": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/tags",
            "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/tags"
          }
        },
        "event_stores": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/event_stores",
            "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/event_stores"
          }
        },
        "skus": {
          "links": {
            "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/skus",
            "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/skus"
          }
        }
      },
      "meta": {
        "mode": "test",
        "organization_id": "xRRkjDFafe",
        "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
      }
    },
    {
      "other": "... 9 buy_x_pay_y_promotions (first page)"
    }
  ],
  "meta": {
    "record_count": 140,
    "page_count": 14
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions?page[number]=1&page[size]=10",
    "next": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions?page[number]=2&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions?page[number]=14&page[size]=10"
  }
}
```

{% endtab %}
{% endtabs %}

Remember that when you fetch a list of resources you get [paginated](https://docs.commercelayer.io/core/pagination) result.

### Sortable fields

The list of buy x pay y promotions can be [sorted](https://docs.commercelayer.io/core/sorting-results) by the following fields:

#### Attributes

* `name`
* `type`
* `currency_code`
* `exclusive`
* `priority`
* `starts_at`
* `expires_at`
* `total_usage_limit`
* `total_usage_count`
* `total_usage_reached`
* `id`
* `disabled_at`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`
* `x`
* `y`

#### Relationships

* `market`
* `sku_list`

### Filterable fields

The list of buy x pay y promotions can be [filtered](https://docs.commercelayer.io/core/filtering-data) by the following fields:

#### Attributes

* `name`
* `type`
* `currency_code`
* `exclusive`
* `priority`
* `starts_at`
* `expires_at`
* `total_usage_limit`
* `total_usage_count`
* `total_usage_reached`
* `id`
* `disabled_at`
* `created_at`
* `updated_at`
* `reference`
* `reference_origin`
* `metadata`
* `x`
* `y`

#### Relationships

* `market`
* `promotion_rules`
* `order_amount_promotion_rule`
* `sku_list_promotion_rule`
* `coupon_codes_promotion_rule`
* `custom_promotion_rule`
* `sku_list`
* `coupons`
* `attachments`
* `events`
* `tags`


# Retrieve a buy x pay y promotion

How to fetch a specific buy x pay y promotion via API

To [fetch](https://docs.commercelayer.io/core/fetching-resources) a single buy x pay y promotion, send a `GET` request to the `/api/buy_x_pay_y_promotions/:id` endpoint, where `id` is the ID of the resource that you want to retrieve.

## Request

**GET** <https://yourdomain.commercelayer.io/api/buy\\_x\\_pay\\_y\\_promotions/:id>

### **Example**

{% tabs %}
{% tab title="Request" %}
The following request fetches the buy x pay y promotion identified by the ID "XAyRWNUzyN":

```shell
curl -g -X GET \
  'https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning a single resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "buy_x_pay_y_promotions",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN"
    },
    "attributes": {
      "name": "Personal promotion",
      "type": "percentage_discount_promotions",
      "currency_code": "EUR",
      "exclusive": true,
      "priority": 2,
      "starts_at": "2018-01-01T12:00:00.000Z",
      "expires_at": "2018-01-02T12:00:00.000Z",
      "total_usage_limit": 5,
      "total_usage_count": 2,
      "total_usage_reached": false,
      "active": true,
      "status": "pending",
      "weight": 112,
      "coupons_count": 2,
      "disabled_at": "2018-01-01T12:00:00.000Z",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      },
      "x": 3,
      "y": 2,
      "cheapest_free": true
    },
    "relationships": {
      "market": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/market",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/market"
        }
      },
      "promotion_rules": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/promotion_rules",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/promotion_rules"
        }
      },
      "order_amount_promotion_rule": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/order_amount_promotion_rule",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/order_amount_promotion_rule"
        }
      },
      "sku_list_promotion_rule": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/sku_list_promotion_rule",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/sku_list_promotion_rule"
        }
      },
      "coupon_codes_promotion_rule": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/coupon_codes_promotion_rule",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/coupon_codes_promotion_rule"
        }
      },
      "custom_promotion_rule": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/custom_promotion_rule",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/custom_promotion_rule"
        }
      },
      "sku_list": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/sku_list",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/sku_list"
        }
      },
      "coupons": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/coupons",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/coupons"
        }
      },
      "attachments": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/attachments",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/attachments"
        }
      },
      "events": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/events",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/events"
        }
      },
      "tags": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/tags",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/tags"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/event_stores"
        }
      },
      "skus": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/skus",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/skus"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Update a buy x pay y promotion

How to update an existing buy x pay y promotion via API

To [update](https://docs.commercelayer.io/core/updating-resources) an existing buy x pay y promotion, send a `PATCH` request to the `/api/buy_x_pay_y_promotions/:id` endpoint, where `id` is the ID of the resource that you want to update.

Here below the list of all the possible arguments that you can pass with the request body.

## Request

**PATCH** <https://yourdomain.commercelayer.io/api/buy\\_x\\_pay\\_y\\_promotions/:id>

### Arguments

| Body Parameter                                   | Type      | Required |
| ------------------------------------------------ | --------- | -------- |
| **type**                                         | `string`  | Required |
| **id**                                           | `string`  | Required |
| attributes.**name**                              | `string`  | Optional |
| attributes.**currency\_code**                    | `string`  | Optional |
| attributes.**exclusive**                         | `boolean` | Optional |
| attributes.**priority**                          | `integer` | Optional |
| attributes.**starts\_at**                        | `string`  | Optional |
| attributes.**expires\_at**                       | `string`  | Optional |
| attributes.**total\_usage\_limit**               | `integer` | Optional |
| attributes.**\_disable**                         | `boolean` | Optional |
| attributes.**\_enable**                          | `boolean` | Optional |
| attributes.**\_add\_tags**                       | `string`  | Optional |
| attributes.**\_remove\_tags**                    | `string`  | Optional |
| attributes.**reference**                         | `string`  | Optional |
| attributes.**reference\_origin**                 | `string`  | Optional |
| attributes.**metadata**                          | `object`  | Optional |
| attributes.**x**                                 | `integer` | Optional |
| attributes.**y**                                 | `integer` | Optional |
| attributes.**cheapest\_free**                    | `boolean` | Optional |
| relationships.**market**                         | `object`  | Optional |
| relationships.**order\_amount\_promotion\_rule** | `object`  | Optional |
| relationships.**sku\_list\_promotion\_rule**     | `object`  | Optional |
| relationships.**coupon\_codes\_promotion\_rule** | `object`  | Optional |
| relationships.**custom\_promotion\_rule**        | `object`  | Optional |
| relationships.**sku\_list**                      | `object`  | Optional |
| relationships.**tags**                           | `array`   | Optional |

### Example

{% tabs %}
{% tab title="Request" %}
The following request updates the buy x pay y promotion identified by the ID "XAyRWNUzyN":

```shell
curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
  "data": {
    "type": "buy_x_pay_y_promotions",
    "id": "xYZkjABcde",
    "attributes": {
      "currency_code": "EUR"
    },
    "relationships": {
      "market": {
        "data": {
          "type": "markets",
          "id": "ABCRtyUpBa"
        }
      }
    }
  }
}'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `200 OK` status code, returning the updated resource object:

```json
{
  "data": {
    "id": "XAyRWNUzyN",
    "type": "buy_x_pay_y_promotions",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN"
    },
    "attributes": {
      "name": "Personal promotion",
      "type": "percentage_discount_promotions",
      "currency_code": "EUR",
      "exclusive": true,
      "priority": 2,
      "starts_at": "2018-01-01T12:00:00.000Z",
      "expires_at": "2018-01-02T12:00:00.000Z",
      "total_usage_limit": 5,
      "total_usage_count": 2,
      "total_usage_reached": false,
      "active": true,
      "status": "pending",
      "weight": 112,
      "coupons_count": 2,
      "disabled_at": "2018-01-01T12:00:00.000Z",
      "created_at": "2018-01-01T12:00:00.000Z",
      "updated_at": "2018-01-01T12:00:00.000Z",
      "reference": "ANY-EXTERNAL-REFEFERNCE",
      "reference_origin": "ANY-EXTERNAL-REFEFERNCE-ORIGIN",
      "metadata": {
        "foo": "bar"
      },
      "x": 3,
      "y": 2,
      "cheapest_free": true
    },
    "relationships": {
      "market": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/market",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/market"
        }
      },
      "promotion_rules": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/promotion_rules",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/promotion_rules"
        }
      },
      "order_amount_promotion_rule": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/order_amount_promotion_rule",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/order_amount_promotion_rule"
        }
      },
      "sku_list_promotion_rule": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/sku_list_promotion_rule",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/sku_list_promotion_rule"
        }
      },
      "coupon_codes_promotion_rule": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/coupon_codes_promotion_rule",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/coupon_codes_promotion_rule"
        }
      },
      "custom_promotion_rule": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/custom_promotion_rule",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/custom_promotion_rule"
        }
      },
      "sku_list": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/sku_list",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/sku_list"
        }
      },
      "coupons": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/coupons",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/coupons"
        }
      },
      "attachments": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/attachments",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/attachments"
        }
      },
      "events": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/events",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/events"
        }
      },
      "tags": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/tags",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/tags"
        }
      },
      "event_stores": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/event_stores",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/event_stores"
        }
      },
      "skus": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/relationships/skus",
          "related": "https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN/skus"
        }
      }
    },
    "meta": {
      "mode": "test",
      "organization_id": "xRRkjDFafe",
      "trace_id": "69abaa3545913c78132e5578bd26208d44aa9043647d78698fd0021f3958cd74"
    }
  }
}
```

{% endtab %}
{% endtabs %}


# Delete a buy x pay y promotion

How to delete an existing buy x pay y promotion via API

To [delete](https://docs.commercelayer.io/core/deleting-resources) a buy x pay y promotion, send a `DELETE` request to the `/api/buy_x_pay_y_promotions/:id` endpoint, where `id` is the id of the buy x pay y promotion that you want to delete.

## Request

**DELETE** <https://yourdomain.commercelayer.io/api/buy\\_x\\_pay\\_y\\_promotions/:id>

### Example

{% tabs %}
{% tab title="Request" %}
The following request tries to delete the buy x pay y promotion identified by the ID "XAyRWNUzyN":

```shell
curl -g -X DELETE \
  'https://yourdomain.commercelayer.io/api/buy_x_pay_y_promotions/XAyRWNUzyN' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Authorization: Bearer your-access-token'
```

{% endtab %}

{% tab title="Response" %}
On success, the API responds with a `204 No Content` status code.
{% endtab %}
{% endtabs %}




---

[Next Page](/llms-full.txt/1)

