> ## Documentation Index
> Fetch the complete documentation index at: https://developer.jtl-software.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Channel API Overview

> Introduction to the JTL Marketplace Channel API: events, metadata, and media content handling.

<Info>
  **The Channel API is available for OnPremise integrations.** Consuming SCX from within a Cloud App is in development and not yet available.
</Info>

With the JTL-Channel API, you can:

* Describe connected marketplace data structure by providing category and attribute data
* Manage product and offer listings
* Update price and quantity of a listing
* Manage orders
* Manage the post-order process (returns, refunds)

## Terminology

The Channel API uses a small set of terms consistently throughout this guide.

| Term           | Definition                                                                                                                                   |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| **Channel**    | A connection to a marketplace or any external system which can be connected to the JTL-Channel API.                                          |
| **Seller**     | A person identified by a unique ID (SellerId) who wants to offer and sell their goods on the connected Channel.                              |
| **Event**      | An action initiated by a seller. A channel needs to react to events in order to create or update a listing or to process post-order actions. |
| **Seller API** | The Channel API counterpart. The ERP system JTL-Wawi is connected with the Seller API.                                                       |

## Development Cycle

This section covers the hosts, prerequisites, and local setup you need to build and test a channel integration.

### API Hosts

The Channel API is available in a sandbox environment for development and a production environment for live traffic.

<CodeGroup>
  ```text Sandbox theme={null}
  https://scx-sbx.api.jtl-software.com
  ```

  ```text Production theme={null}
  https://scx.api.jtl-software.com
  ```
</CodeGroup>

### Prerequisites

To access the JTL-Channel API you need an API refresh token. These tokens are created during the onboarding process
together with JTL. Sellers connect to a channel with an eazyAuction subscription. If you are interested in connecting your
marketplace with the JTL ecosystem, please [contact us](https://www.jtl-software.de/kontakt).

### Development

The Channel implementation runs on your own infrastructure. You as the Channel integrator have the full responsibility to
run, manage, and secure your application.

### Error Handling

Error responses are indicated by an HTTP status code >= 400. The Channel API uses a consistent error response format:

```json theme={null}
{
  "errorList": [
    {
      "code": "VAL100",
      "message": "orderList[0].sellerId: SellerId must not be empty and may contain a maximum of 50 alphanumeric characters",
      "severity": "error",
      "hint": null
    },
    {
      "code": "VAL100",
      "message": "orderList[0].orderStatus: Invalid or unknown Order Status. Must be one of UNACKED, CREATED, ACCEPTED, SHIPPED, PARTIALLY_SHIPPED, CANCELED_BY_SELLER, CANCELED_BY_BUYER",
      "severity": "error",
      "hint": null
    }
  ]
}
```

<Tip>
  The default language for error messages is German (`de`). You can switch to English by setting the `Accept-Language: en` header.
</Tip>

### Setting Up a Local JTL-Wawi Instance

You can use the JTL-Wawi ERP system during development to create new listings or manage orders.

<Steps>
  <Step title="Install JTL-Wawi">
    [Install JTL-Wawi](https://www.jtl-software.com/de/warenwirtschaftssystem-software/jtl-wawi-download/) version 1.8 or higher to connect with the sandbox environment.
  </Step>

  <Step title="Add the seller refresh token">
    Connect to the MSSQL Server directly and insert the seller's refresh token (created during onboarding):

    ```sql theme={null}
    INSERT INTO SCX.tRefreshToken
    (cRefreshToken, nType)
    VALUES
    (N'<SellerAPI-RefreshToken>', 1);
    ```
  </Step>

  <Step title="Switch the API host to Sandbox">
    ```sql theme={null}
    UPDATE dbo.tOptions
    SET cValue = 'https://scx-sbx.api.jtl-software.com'
    WHERE ckey = 'SCX.URL'
    ```
  </Step>

  <Step title="Restart JTL-Wawi">
    Restart JTL-Wawi to apply the changes.
  </Step>
</Steps>

### Using the Seller API Directly

To test workflows and send test data to the Channel API, you can use the Seller API directly.
See the [Seller API reference](/api-reference/scx/seller) and the [Postman Collection](https://www.postman.com/jtl-eazyauction/workspace/jtl-scx-public).

## Events

Two important components of SCX are **seller events** and **channel events**. Seller events are emitted by a seller integration such
as JTL-Wawi. Channel events are emitted by a channel integration. Such events are actions created by an actor
(either a seller or a channel) and may be handled by connected integrations.

A channel integration needs to handle the various seller events provided by `GET /v1/channel/event` in order to create new
listings, and mark orders as paid or shipped.

```mermaid theme={null}
sequenceDiagram
    participant Seller as Seller (JTL-Wawi)
    participant SCX as SCX Platform
    participant Channel as Channel Integration

    Seller->>SCX: Emits seller event (e.g. Offer.New)
    SCX->>SCX: Queues event for channel

    loop Poll every ~60 seconds
        Channel->>SCX: GET /v1/channel/event
        SCX-->>Channel: Returns eventList
    end

    Channel->>Channel: Process events
    Channel->>SCX: DELETE /v1/channel/event (acknowledge)
```

<Note>
  We recommend calling the seller event endpoint at regular intervals (such as once a minute) and consuming all available events.
</Note>

When an event is consumed, it **must** be acknowledged by calling `DELETE /v1/channel/event`. Otherwise, the event will be
transmitted again after a timeout.

<Warning>
  An event will be transmitted a maximum of 10 times. Afterwards it will be marked as a dead-letter and will
  not be transmitted again.
</Warning>

### Seller Event Types

Seller events fall into three groups: offer events, order events, and seller meta events.

<AccordionGroup>
  <Accordion title="Offer Events">
    | Event Type                 | Description                                                     |
    | -------------------------- | --------------------------------------------------------------- |
    | `Seller:Offer.New`         | A new listing/offer was created by the seller                   |
    | `Seller:Offer.Update`      | An existing listing/offer was updated                           |
    | `Seller:Offer.StockUpdate` | Stock quantity changed (deprecated, use stock update endpoints) |
    | `Seller:Offer.PriceUpdate` | Price changed for an existing offer                             |
  </Accordion>

  <Accordion title="Order Events">
    | Event Type                            | Description                                        |
    | ------------------------------------- | -------------------------------------------------- |
    | `Seller:Order.Shipping`               | Seller has shipped (or partially shipped) an order |
    | `Seller:Order.Payment`                | Payment status changed                             |
    | `Seller:Order.CancellationAccepted`   | Seller accepted a cancellation request             |
    | `Seller:Order.CancellationDenied`     | Seller denied a cancellation request               |
    | `Seller:Order.Refund`                 | Seller initiated a refund                          |
    | `Seller:Order.ReturnProcessingResult` | Seller processed a return                          |
  </Accordion>

  <Accordion title="Seller Meta Events">
    | Event Type                                  | Description                                        |
    | ------------------------------------------- | -------------------------------------------------- |
    | `Seller:Meta.SellerAttributesUpdateRequest` | Seller requested to update their seller attributes |
    | `Seller:Channel.Unlinked`                   | Seller unlinked from the channel                   |
  </Accordion>
</AccordionGroup>

### Receiving Seller Events

A `GET /v1/channel/event` call returns an `eventList` containing the queued events for your channel.

```json theme={null}
// GET /v1/channel/event
{
  "eventList": [
    {
      "id": "63623b997d2c89a4e3e9f3c7",
      "event": {
        "channel": "WAWIDEV001",
        "sellerId": "EA4590MitName"
      },
      "createdAt": "2022-11-02T09:42:49+00:00",
      "type": "Seller:Meta.SellerAttributesUpdateRequest"
    },
    {
      "id": "636280fd498628e9f0b28984",
      "event": {
        "sellerId": "1",
        "offerId": 822,
        "channelCategoryId": "CAT7",
        "quantity": "0",
        "taxPercent": "19",
        "priceList": [
          {
            "id": "B2C",
            "quantityPriceList": [
              {
                "quantity": "1",
                "amount": "19.99",
                "currency": "EUR"
              }
            ]
          }
        ],
        "title": "Fahrrad Halterung",
        "channelAttributeList": [
          {
            "attributeId": "WAWI-61427_number_category",
            "value": "954",
            "group": "0"
          }
        ],
        "sku": "843609"
      },
      "createdAt": "2022-11-02T14:38:53+00:00",
      "type": "Seller:Offer.New"
    }
  ]
}
```

### Acknowledging Events

After processing, acknowledge the received events so they are not retransmitted:

```json theme={null}
// DELETE /v1/channel/event
{
  "eventIdList": [
    "63623b997d2c89a4e3e9f3c7",
    "636280fd65a66c4430ec0d67"
  ]
}
```

## Metadata

Within the SCX context, there is no concept of a product catalogue. Instead, only listing data is transmitted via the SCX interface. Depending on the channel's requirements, this listing data may also include detailed product information.

A channel provides descriptive information that defines what a listing can look like on a connected marketplace. This descriptive information is called **Metadata**.

```mermaid theme={null}
graph TD
    A[Channel Metadata] --> B[Price Types]
    A --> C[Category Tree]
    A --> D[Attributes]

    D --> D1[Global Attributes]
    D --> D2[Category Attributes]
    D --> D3[Seller Attributes]
    D --> D4[Item-specific Attributes]
```

### Price Types

There must be at least one price type available to create a listing on a connected marketplace.
Examples of price types are B2C or B2B prices.

```json theme={null}
// POST /v1/channel/price
{
  "priceTypeId": "MarketplaceTypeId",
  "displayName": "Marketplace Price",
  "description": "Selling price on Marketplace"
}
```

The `priceTypeId` will be transmitted with the `Seller:Offer.New` or `Seller:Offer.Update` seller events:

```json theme={null}
{
  "sellerId": "1",
  "offerId": 4711,
  "channelCategoryId": "Stuff",
  "quantity": "508.00",
  "taxPercent": "19",
  "priceList": [
    {
      "id": "MarketplaceTypeId",
      "quantityPriceList": [
        {
          "amount": "6.95",
          "currency": "EUR",
          "quantity": "1"
        }
      ]
    }
  ]
}
```

### Category Tree

A connected channel may provide a category structure to set specific attributes related to a category.

<Note>
  The API endpoint replaces the entire category structure on each call.
</Note>

```json theme={null}
// PUT /v1/channel/categories
{
  "categoryList": [
    {
      "categoryId": "1",
      "displayName": "First Category",
      "listingAllowed": false,
      "parentCategoryId": "0"
    },
    {
      "categoryId": "1.1",
      "displayName": "First Leaf Category",
      "listingAllowed": true,
      "parentCategoryId": "1"
    },
    {
      "categoryId": "1.2",
      "displayName": "Second Leaf Category",
      "listingAllowed": true,
      "parentCategoryId": "1"
    }
  ]
}
```

### Attributes

Attributes provide a simple way of describing a listing for a channel. This lets the channel
define all marketplace requirements for a listing as attributes. SCX differentiates between the following attribute types:

<Tabs>
  <Tab title="Global Attributes">
    Global attributes should be used when data is required for each listing.

    These are set via `PUT /v1/channel/attribute/global` and apply to all listings regardless of category.
  </Tab>

  <Tab title="Category Attributes">
    Category attributes are related to a `categoryId` inside the category structure. JTL-Wawi will display these attributes
    only when the listing is part of a given category.

    These are set via `POST /v1/channel/attribute/category/{categoryId}`.
  </Tab>

  <Tab title="Seller Attributes">
    Seller attributes are global attributes and can be used when a seller requires individual settings for their listings.

    These are set via `POST /v1/channel/attribute/seller`.
  </Tab>

  <Tab title="Item-specific Attributes">
    Item-specific attributes are not specified by the channel but are instead created and transferred by the seller.
    Each attribute must provide a simple, non-schematic, key-value data structure. These attributes will be transmitted
    along with the `channelAttributeList` in each `Seller:Offer.New` or `Seller:Offer.Update` event.

    These attributes are highly specific and depend on the input of the seller. The channel can use these attributes to
    provide product and listing data.
  </Tab>
</Tabs>

#### Attribute Types Reference

Each attribute is declared with one of the following types.

| Type        | Description                              |
| ----------- | ---------------------------------------- |
| `smalltext` | Short text value                         |
| `text`      | Longer text value                        |
| `integer`   | Integer number                           |
| `decimal`   | Decimal number                           |
| `boolean`   | True/false value                         |
| `enum`      | Enumerated value with predefined options |
| `htmltext`  | HTML-formatted text                      |
| `date`      | Date value                               |
| `image`     | Link to an image file                    |
| `document`  | Link to a document file                  |

#### Attributes with Different Types

The following request registers one attribute of each supported type against a category.

```json theme={null}
// POST /v1/channel/attribute/category/DEMO-TYPES
// DEMO-TYPES is a categoryId created earlier via PUT /v1/channel/categories
{
  "attributeList": [
    {
      "attributeId": "DEMO-TYPES_smalltext",
      "displayName": "Smalltext",
      "type": "smalltext"
    },
    {
      "attributeId": "DEMO-TYPES_text",
      "displayName": "Text",
      "type": "text"
    },
    {
      "attributeId": "DEMO-TYPES_integer",
      "displayName": "Integer",
      "type": "integer"
    },
    {
      "attributeId": "DEMO-TYPES_decimal",
      "displayName": "Decimal",
      "type": "decimal"
    },
    {
      "attributeId": "DEMO-TYPES_boolean",
      "displayName": "Boolean",
      "type": "boolean"
    },
    {
      "attributeId": "DEMO-TYPES_enum",
      "displayName": "Enum",
      "type": "enum",
      "values": [
        { "display": "Value 1", "value": "Id1", "sort": 10 },
        { "display": "Value 2", "value": "Id2", "sort": 20 },
        { "value": "This has no Display" }
      ]
    },
    {
      "attributeId": "DEMO-TYPES_htmltext",
      "displayName": "Html-text",
      "type": "htmltext"
    },
    {
      "attributeId": "DEMO-TYPES_date",
      "displayName": "Date",
      "type": "date"
    },
    {
      "attributeId": "DEMO-TYPES_image",
      "displayName": "Image",
      "description": "Link to Image file",
      "type": "image"
    },
    {
      "attributeId": "DEMO-TYPES_document",
      "displayName": "Document",
      "description": "Link to a Document file",
      "type": "document"
    }
  ]
}
```

#### Using Sections and Sub-sections

You can organize attributes into logical groups using sections and sub-sections:

```json theme={null}
// POST /v1/channel/attribute/category/DEMO-SECTIONS
// DEMO-SECTIONS is a categoryId created earlier via PUT /v1/channel/categories
{
  "attributeList": [
    {
      "attributeId": "DEMO-SECTIONS_WAREHOUS",
      "displayName": "Warehouse",
      "type": "smalltext",
      "section": "Shipping",
      "sectionPosition": 100
    },
    {
      "attributeId": "DEMO-SECTIONS_SHIPPING",
      "displayName": "Shipping Group",
      "type": "smalltext",
      "section": "Shipping",
      "sectionPosition": 80
    },
    {
      "attributeId": "DEMO-SECTIONS_LEADTIME",
      "displayName": "Lead time until shipment",
      "type": "integer",
      "section": "Shipping",
      "sectionPosition": 50
    },
    {
      "attributeId": "DEMO-SECTIONS_OFFER_START",
      "displayName": "Start",
      "type": "date",
      "section": "Discount",
      "sectionPosition": 50
    },
    {
      "attributeId": "DEMO-SECTIONS_OFFER_DISCOUNT",
      "displayName": "Discount Value",
      "type": "decimal",
      "section": "Discount",
      "sectionPosition": 100,
      "subSection": "Deduction",
      "subSectionPosition": 100
    },
    {
      "attributeId": "DEMO-SECTIONS_OFFER_DISCOUNT_UNIT",
      "displayName": "Discount Unit",
      "type": "enum",
      "values": [
        { "value": "%" },
        { "value": "EUR" }
      ],
      "section": "Discount",
      "sectionPosition": 100,
      "subSection": "Deduction",
      "subSectionPosition": 90
    }
  ]
}
```

#### Multiple-value Attributes

It is possible to create repeatable attributes if the attribute supports multiple values:

```json theme={null}
// POST /v1/channel/attribute/category/DEMO-MULTIPLY_ALLOWED
// DEMO-MULTIPLY_ALLOWED is a categoryId created earlier via PUT /v1/channel/categories
{
  "attributeList": [
    {
      "attributeId": "DEMO-TYPES_isMultipleAllowed",
      "displayName": "Attribute is Multiple Allowed",
      "isMultipleAllowed": true,
      "type": "smalltext"
    }
  ]
}
```

#### Repeatable Sub-sections

You can also create repeatable sub-sections for grouped attribute sets:

```json theme={null}
// POST /v1/channel/attribute/category/DEMO-REPEATABLE_SUBSECTIONS
// DEMO-REPEATABLE_SUBSECTIONS is a categoryId created earlier via PUT /v1/channel/categories
{
  "attributeList": [
    {
      "attributeId": "shipping_carrier",
      "displayName": "Versanddienstleister",
      "type": "enum",
      "values": [
        { "value": "carrierID_2", "display": "Brief", "sort": 1 },
        { "value": "carrierID_3", "display": "DHL Paeckchen", "sort": 2 },
        { "value": "carrierID_4", "display": "DHL Paket", "sort": 3 },
        { "value": "carrierID_22", "display": "Kostenloser Download", "sort": 20 }
      ],
      "section": "Versandkosten",
      "sectionPosition": 2,
      "subSection": "Versandart",
      "subSectionPosition": 10,
      "isRepeatableSubSection": true
    },
    {
      "attributeId": "shipping_cost_nat",
      "displayName": "National",
      "type": "decimal",
      "section": "Versandkosten",
      "sectionPosition": 2,
      "subSection": "Versandart",
      "subSectionPosition": 9,
      "isRepeatableSubSection": true
    },
    {
      "attributeId": "shipping_cost_eu",
      "displayName": "EU",
      "type": "decimal",
      "section": "Versandkosten",
      "sectionPosition": 2,
      "subSection": "Versandart",
      "subSectionPosition": 8,
      "isRepeatableSubSection": true
    },
    {
      "attributeId": "shipping_cost_int",
      "displayName": "International",
      "type": "decimal",
      "section": "Versandkosten",
      "sectionPosition": 2,
      "subSection": "Versandart",
      "subSectionPosition": 7,
      "isRepeatableSubSection": true
    }
  ]
}
```

When using repeatable sections, JTL-Wawi generates a group ID which is then transferred back to the channel with the
listing. This makes it possible to recognize related attributes in the listing data:

```json theme={null}
// GET /v1/channel/event: Offer with repeatable sub-sections
{
  "type": "Seller:Offer.New",
  "sellerId": "1",
  "offerId": 1,
  "channelCategoryId": "DEMO-REPEATABLE_SUBSECTIONS",
  "channelAttributeList": [
    { "attributeId": "shipping_carrier", "value": "DHL Paket", "group": "1" },
    { "attributeId": "shipping_cost_nat", "value": "2.99", "group": "1" },
    { "attributeId": "shipping_cost_eu", "value": "2.99", "group": "1" },
    { "attributeId": "shipping_cost_int", "value": "9.99", "group": "1" },
    { "attributeId": "shipping_carrier", "value": "Brief", "group": "2" },
    { "attributeId": "shipping_cost_nat", "value": "1.20", "group": "2" },
    { "attributeId": "shipping_cost_eu", "value": "2.40", "group": "2" },
    { "attributeId": "shipping_cost_int", "value": "2.40", "group": "2" }
  ]
}
```

## Media Content Handling

The SCX system **emits** seller events containing media file links; channels **receive** these events but do **not** generate them.

### Media Fields in Events and Attributes

Media reaches a channel through event payload fields and through channel-defined attributes.

* Events provided by SCX include `pictureList` and `mainPicture` in both `Seller:Offer.New` and `Seller:Offer.Update` payloads.
  These fields are URLs to image files.
* Any channel-specific attribute defined as type `image` or `document` also appears as a URL to the corresponding file.

### Defining Media Attributes

Channels can register attributes of type `image` or `document`:

```json theme={null}
// PUT /v1/channel/attribute/global
{
  "attributeList": [
    {
      "attributeId": "DEMO-TYPES_image",
      "displayName": "Image",
      "description": "Link to Image file",
      "type": "image"
    },
    {
      "attributeId": "DEMO-TYPES_document",
      "displayName": "Document",
      "description": "Link to a Document file",
      "type": "document"
    }
  ]
}
```

### File URL Structure

All media links are hosted on S3-compatible storage and follow this pattern:

```
https://s3.api.jtl-software.com/scx-api/public/{media-hash}.{ext}
```

Where:

* `{media-hash}` is the SHA-1 hash of the file contents.
* `{ext}` is the file extension (`gif`, `jpg`, `png`, `svg`, or `pdf`).

### Media URL Lifetime

Media links expire, so plan for retrieval within a fixed window.

<Warning>
  Media URLs remain valid for **7 days** after event generation. After this period, requests may return HTTP 404 or 403.
  If your marketplace integration requires access beyond 7 days, you **must** proactively fetch and store or rehost the file.
</Warning>

### Supported Formats and Size Limits

The Channel API accepts the following media MIME types and extensions.

| MIME Type         | Extension |
| ----------------- | --------- |
| `image/gif`       | `gif`     |
| `image/jpeg`      | `jpg`     |
| `image/pjpeg`     | `jpg`     |
| `image/png`       | `png`     |
| `image/x-png`     | `png`     |
| `image/svg+xml`   | `svg`     |
| `application/pdf` | `pdf`     |

Maximum file size is **16 MB** per media file. Files that do not match these MIME types or exceed the size limit may be rejected.

### Example: `Seller:Offer.New` Event with Media

The following payload shows how media URLs appear in an offer event.

```json theme={null}
{
  "type": "Seller:Offer.New",
  "sellerId": "MYSELLERID",
  "offerId": 1,
  "mainPicture": "https://s3.api.jtl-software.com/scx-api/public/ca953...872.jpg",
  "pictureList": [
    "https://s3.api.jtl-software.com/scx-api/public/ff5a3...4c3.jpg",
    "https://s3.api.jtl-software.com/scx-api/public/11aa2...p77.png"
  ],
  "channelAttributeList": [
    {
      "attributeId": "thumbnailImage",
      "value": "https://s3.api.jtl-software.com/scx-api/public/aabbc...899.pdf"
    }
  ]
}
```

***

## What's Next?

<CardGroup cols={2}>
  <Card title="Product Sync" icon="refresh-cw" href="/guides/marketplace-channels/product-sync">
    Learn how to synchronize product and offer listings with marketplace channels.
  </Card>

  <Card title="Order Management" icon="box" href="/guides/marketplace-channels/order-management">
    Handle orders, cancellations, returns, and refunds across channels.
  </Card>

  <Card title="Seller Management" icon="workflow" href="/guides/marketplace-channels/seller-management">
    Seller sign-up, update, and unlink flows.
  </Card>

  <Card title="Authorization" icon="key" href="/guides/marketplace-channels/authorization">
    Refresh tokens, access tokens, and Bearer headers for all SCX APIs.
  </Card>

  <Card title="Channel API Reference" icon="code" href="/api-reference/scx/channel">
    Full endpoint reference for the Channel API.
  </Card>

  <Card title="Postman Collection" icon="send" href="https://www.postman.com/jtl-eazyauction/workspace/jtl-scx-public">
    Ready-made requests for the Channel and Seller APIs.
  </Card>
</CardGroup>
