[Skip to main content](#vessel-content)

☰ Documentation

#  Connector API

Details    Written by: jobsigen    Category: [Developer area](/support/documentation/hikashop/developer-area)     Published: 05 November 2026     Hits: 836

# HikaShop Connector API

https://your-shop.tld/hikashop-api/v1   Version  6.7.0  (current)    [YAML](https://www.hikashop.com/images/doc/hk/api/connector-api-6.7.0.yaml "OpenAPI 3.1, YAML") [JSON](https://www.hikashop.com/images/doc/hk/api/connector-api-6.7.0.json "OpenAPI 3.1, JSON") [MARKDOWN](https://www.hikashop.com/images/doc/hk/api/connector-api-6.7.0.md "One flat file, for an assistant")

## Overview

The connector plugin ships inside HikaShop Business and answers JSON over HTTPS. The mobile application is one client of it; anything it does, your own code can do.

Every response carries the same envelope, `{"data": …, "meta": …, "error": null}`, and every route except `POST /pair` carries a device token as `Authorization: Bearer <token>`. A token holds the scopes `read` and optionally `write`, and the operator it is bound to keeps their own access levels, so a device may hold `write` and still be refused an order its operator cannot see.

The base path is a plugin parameter and a shop can move it. Nothing else here changes between shops.

```
{
  <span class="k">"data"</span>: { … },
  <span class="k">"meta"</span>: <span class="n">null</span>,
  <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Pairing a device

A client never sees the merchant's password. It is given a **pairing code** instead, generated in **System &gt; App Devices** of the backend, and exchanges it once for a token of its own.

The code is nine characters, lives five minutes, may be tried five times before it dies, and can only be spent once. `POST /pair` is rate limited to thirty attempts per minute per address, which is the only route that answers without a token.

What comes back is the token, the scopes the code granted, and the id of the device row. The token is shown once and stored only as a SHA-256 hash, so a device that loses it pairs again rather than recovering it. Revoking a device is deleting its row in that same screen, and every token it held stops working at once.

```
curl -X POST "$SHOP/hikashop-api/v1/pair" \
  -H "Content-Type: application/json" \
  -d '{ "code": "K7QM-2F84", "device_name": "Counter tablet" }'

# then, for everything else
curl "$SHOP/hikashop-api/v1/products" \
  -H "Authorization: Bearer $TOKEN"
```

## Scopes and access levels

Two separate checks run on every request, and the narrower one wins.

The **scope** is what the device may do at all: `read`, and `write` if the pairing code granted it. A device without `write` is refused every route that changes anything, whoever holds it.

The **access levels** are the shop's own, belonging to the operator the device is bound to. They decide which records that person may see and change, exactly as they do in the backend. So a device holding `write` can still be refused an order, and a device holding only `read` sees a smaller catalogue than another one.

This is why an integration should be given its own device rather than borrowing one: revoke it and nothing else is disturbed, and its operator's access levels are the ceiling on what it can reach.

```
{
  "data": null,
  "error": {
    "code": "forbidden",
    "message": "This device does not have the required scope."
  }
}
```

## The envelope, errors and paging

Every JSON answer has the same three keys. `data` is the payload, `meta` carries paging and other context when there is any and is `null` otherwise, and `error` is `null` on success.

On failure `data` is `null` and `error` holds a stable `code` and a human `message`. Read the code, not the message: the message is written for a person and may be translated or reworded, the code is what your own logic should branch on.

Listings page with `start` and `limit` in the query, and answer with `start`, `limit` and `total` in the envelope's `meta`. `total` counts the rows matching the filter before paging, so it is how you know there is another page. `limit` is capped, usually at a hundred, and asking for more silently gets you the cap rather than an error.

One thing to note about a listing: `data` is the list itself, not an object wrapping it. The paging lives in `meta`.

### Codes every route can return

CodeHTTPMeans

invalid\_request400A required field is missing or malformed.

unauthorized401No token, or a token that is unknown, revoked or unpublished.

forbidden403The device lacks the scope, or the operator lacks the access level.

not\_found404No such record, or no such route. Also returned when the operator may not see the record, so that it cannot be probed for.

too\_many\_requests429Rate limited. Only /pair does this.

```
{
  "data": [ … ],
  "meta": { "start": 0, "limit": 20, "total": 307 },
  "error": null
}
```

## Calling it from a browser

The API answers cross-origin requests, because the application is a web application as well as a phone one. `Access-Control-Allow-Origin` is `*`, the allowed methods are GET, POST, PUT, DELETE and OPTIONS, and the allowed headers are `Authorization`, `Content-Type` and `X-Hikashop-Token`. A preflight is answered immediately and may be cached for a day.

`*` with a bearer token is deliberate and safe in the way cookies would not be: nothing is sent automatically by the browser, so a page on another origin can only call this API if it already holds a token, and a token is only ever obtained by pairing.

Send the token in the `Authorization` header. Never put it in the query string, where it would be written to every access log between you and the shop.

```
OPTIONS /hikashop-api/v1/products

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type, X-Hikashop-Token
Access-Control-Max-Age: 86400
```

## Adding information and settings to customers, orders and products

Since 6.7.0, a plugin can add to the records the connector already serves, rather than serving a path of its own: something to **show** on a customer, an order or a product, and settings to **edit** there. A client draws both without knowing the plugin exists, so an add-on reaches the mobile application, a helpdesk or your own code with no work on their side.

The detail of a customer, an order or a product carries two lists, empty when no plugin answers:

\- `sections`, information to display. A section has a `key` (namespace it with your plugin's name), a `title` and `rows`. A row has a `label` and a `value` already formatted for display (the shop knows the currency, the date format and the language; the client does not), and optionally a `url`, a `badge` (`text` and a `tone`: `neutral`, `success`, `warning` or `danger`) and a `ref` to another record (`type` `customer`, `order` or `product`, and its `id`). - `extensions`, groups of settings. A group has a `key`, a `title` and `fields`, each described like the shop's own custom fields (`namekey`, `type`, `label`, `required`, `options`...) plus its current `value`, a string. The types are `text`, `textarea`, `number`, `email`, `url`, `boolean`, `singledropdown`, `multipledropdown`, `radio`, `checkbox`, `date`, `datetime` and `wysiwyg`; anything else is dropped, so a plugin cannot hand a client something it cannot draw. A client that does not know a type shows a text input, which is why `boolean` also carries yes/no options. A field may be `readonly`.

To save, send `extensions` with the record's usual save (`PUT /customers/{id}`, `PUT /products/{id}`, `PUT /orders/{id}/fields`) as `{ "group key": { "namekey": "value" } }`. The record's own fields are saved first, then each group, and each plugin only receives its own group's values, for the fields it declared. A plugin refusing a value answers per field, and the route returns `invalid_extensions` with those messages in `error.details`, keyed by group and then field.

Three events, each given one object by reference: `onConnectorElementSections` and `onConnectorElementForm` carry `type`, `id` and `device`, and your plugin appends to `sections` or `groups`; `onConnectorElementSave` also carries `group` and `values`, and your plugin fills `errors` (namekey =&gt; message) when it refuses something. Check `type` first: every plugin hears every record.

```
public function onConnectorElementSections(&$ctx) {
    if ($ctx->type !== 'product' || !$this->isAuction($ctx->id))
        return;
    $ctx->sections[] = array('key' => 'auction.bids', 'title' => 'Bids', 'rows' => array(
        array('label' => 'Highest bid', 'value' => '120.00 EUR'),
        array('label' => 'Ends', 'value' => '3 October 2026 18:00',
            'badge' => array('text' => 'ending soon', 'tone' => 'warning')),
    ));
}

public function onConnectorElementForm(&$ctx) {
    if ($ctx->type !== 'product')
        return;
    $ctx->groups[] = array('key' => 'auction', 'title' => 'Auction', 'fields' => array(
        array('namekey' => 'auction_end', 'type' => 'datetime', 'label' => 'Ends',
            'required' => true, 'value' => $this->endOf($ctx->id)),
        array('namekey' => 'auction_reserve', 'type' => 'number', 'label' => 'Reserve price',
            'value' => $this->reserveOf($ctx->id)),
    ));
}

public function onConnectorElementSave(&$ctx) {
    if ($ctx->type !== 'product' || $ctx->group !== 'auction')
        return;
    if (isset($ctx->values['auction_reserve']) && $ctx->values['auction_reserve'] < 0)
        $ctx->errors['auction_reserve'] = 'The reserve cannot be negative.';
    else
        $this->store($ctx->id, $ctx->values);
}
```

## Adding your own routes

A HikaShop plugin can serve paths of its own through the same base path, the same envelope and the same authentication, by listening to three events.

`onConnectorBeforeRoute` fires before any matching, so it can intercept a path the connector also serves. `onConnectorRoute` fires only when nothing matched, which is where a new path belongs. `onConnectorBeforeResponse` fires just before the JSON is written, for adding a field to an answer somebody else built.

The listener receives one object by reference, carrying `path` (the part after the base path), `method`, `base_path`, `response`, and `handled`. Authenticate with `requireScope()` exactly as the connector's own routes do, answer through `$ctx->response`, and set `$ctx->handled = true` so the router stops rather than falling through to its 404.

```
public function onConnectorRoute(&$ctx) {
    if ($ctx->path !== 'warehouse/stock' || $ctx->method !== 'GET')
        return;

    $device = HikashopConnectorAuth::requireScope($ctx->response, 'read');
    if ($device === null)
        return;          // it has already answered 401 or 403

    $ctx->response->data(array('pallets' => $this->countPallets()));
    $ctx->handled = true;
}
```

## What this shop is

GET /site read since 6.6.0

The first call a client makes. It says what it has connected to, who it is connected as, and what that operator is allowed to do, which is enough to draw an interface without asking for anything it will only be refused.

Nothing here changes often. Cache it, and use `GET /version` to know when to look again.

### Response expand all

FieldTypeDescription

appstringAlways `hikashop-connector`. A cheap way to be sure you are talking to this API and not to something else answering on that path.

api\_versionstringSemver of the API itself, not of HikaShop. A minor bump adds fields or routes, a major one breaks something.

site\_namestringWhat the site calls itself, which is what a merchant recognises the shop by.

hikashop\_versionstring\|nullThe HikaShop release running there.

cmsobjectWhat it is running on.nameboolean`joomla` or `wordpress`.

versionstring\|nullThe CMS release.

editionstring`starter`, `essential` or `business`. This API only answers on Business, so in practice it is `business` unless the licence has lapsed.

logostringThe shop's logo as an absolute URL, empty when none is set. The same setting the invoices use.

currencyobjectThe shop's money.defaultintegerThe currency id, a row in the shop's own table, not an ISO code.

price\_with\_taxbooleanWhether prices are shown to customers with tax included. Display only: the prices in this API are as stored.

operatorobjectThe user the device is bound to.idinteger`0` when the device is bound to nobody, which is a device paired without an operator.

namestring\|nullTheir display name.

rolestring`admin` when they may manage the component, `staff` otherwise.

scopesstring\[\]What this device may do: `read`, and `write` when it was granted.

permissionsobjectWhat the operator's access levels allow, keyed by resource (`product`, `order`, `category`, `discount`, `user`, `zone`, `characteristic`, `massaction`, `dashboard`), each with `view`, `manage` and `delete`. Use it to leave controls out rather than showing a screen full of refusals. Its keys are the resources this HikaShop knows about, so an add-on can add one.

capabilitiesobjectWhat this shop can do beyond the basics.posbooleanReserved for the point of sale, false for now.

pushbooleanReserved for push notifications, false for now.

multivendorbooleanWhether HikaMarket is installed.

```
curl "$SHOP/hikashop-api/v1/site" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"app"</span>: <span class="s">"hikashop-connector"</span>,
        <span class="k">"api_version"</span>: <span class="s">"1.0.0"</span>,
        <span class="k">"site_name"</span>: <span class="s">"HikaShop Test"</span>,
        <span class="k">"hikashop_version"</span>: <span class="s">"6.6.0"</span>,
        <span class="k">"cms"</span>: {
            <span class="k">"name"</span>: <span class="s">"joomla"</span>,
            <span class="k">"version"</span>: <span class="s">"6.1.1"</span>
        },
        <span class="k">"edition"</span>: <span class="s">"essential"</span>,
        <span class="k">"logo"</span>: <span class="s">""</span>,
        <span class="k">"currency"</span>: {
            <span class="k">"default"</span>: <span class="n">1</span>
        },
        <span class="k">"price_with_tax"</span>: <span class="n">true</span>,
        <span class="k">"operator"</span>: {
            <span class="k">"id"</span>: <span class="n">0</span>,
            <span class="k">"name"</span>: <span class="n">null</span>,
            <span class="k">"role"</span>: <span class="s">"staff"</span>
        },
        <span class="k">"scopes"</span>: [
            "read",
            "write"
        ],
        <span class="k">"permissions"</span>: {
            <span class="k">"category"</span>: {
                <span class="k">"view"</span>: <span class="n">true</span>,
                <span class="k">"manage"</span>: <span class="n">true</span>,
                <span class="k">"delete"</span>: <span class="n">true</span>
            },
            <span class="k">"characteristic"</span>: {
                <span class="k">"view"</span>: <span class="n">true</span>,
                <span class="k">"manage"</span>: <span class="n">true</span>,
                <span class="k">"delete"</span>: <span class="n">true</span>
            },
            <span class="k">"product"</span>: {
                <span class="k">"view"</span>: <span class="n">true</span>,
                <span class="k">"manage"</span>: <span class="n">true</span>,
                <span class="k">"delete"</span>: <span class="n">true</span>
            },
            <span class="k">"order"</span>: {
                <span class="k">"view"</span>: <span class="n">true</span>,
                <span class="k">"manage"</span>: <span class="n">true</span>,
                <span class="k">"delete"</span>: <span class="n">true</span>
            },
            <span class="k">"discount"</span>: {
                <span class="k">"view"</span>: <span class="n">true</span>,
                <span class="k">"manage"</span>: <span class="n">true</span>,
                <span class="k">"delete"</span>: <span class="n">true</span>
            },
            <span class="k">"user"</span>: {
                <span class="k">"view"</span>: <span class="n">true</span>,
                <span class="k">"manage"</span>: <span class="n">true</span>,
                <span class="k">"delete"</span>: <span class="n">true</span>
            },
            <span class="k">"zone"</span>: {
                <span class="k">"view"</span>: <span class="n">true</span>,
                <span class="k">"manage"</span>: <span class="n">true</span>,
                <span class="k">"delete"</span>: <span class="n">true</span>
            },
            <span class="k">"dashboard"</span>: {
                <span class="k">"view"</span>: <span class="n">true</span>,
                <span class="k">"manage"</span>: <span class="n">true</span>,
                <span class="k">"delete"</span>: <span class="n">true</span>
            },
            <span class="k">"massaction"</span>: {
                <span class="k">"view"</span>: <span class="n">true</span>,
                <span class="k">"manage"</span>: <span class="n">true</span>,
                <span class="k">"delete"</span>: <span class="n">true</span>
            }
        },
        <span class="k">"capabilities"</span>: {
            <span class="k">"pos"</span>: <span class="n">false</span>,
            <span class="k">"push"</span>: <span class="n">false</span>,
            <span class="k">"multivendor"</span>: <span class="n">false</span>
        }
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## The settings that decide how prices read

GET /settings read since 6.6.0

The handful of configuration flags a client needs in order to show the same figures the shop's own pages show. They are read only here; they are changed in the backend.

### Response expand all

FieldTypeDescription

product\_contactbooleanWhether products can be enquired about rather than bought.

product\_waitlistbooleanWhether customers can join a waiting list for something out of stock.

price\_with\_taxbooleanShow prices with tax included.

floating\_tax\_pricesbooleanWhether the tax shown depends on the customer, which means a price cannot be cached across customers.

show\_original\_pricebooleanShow the price before a discount alongside the discounted one.

round\_calculationsintegerWhen rounding happens during a calculation. Match it or your totals will differ from the shop by a cent.

```
curl "$SHOP/hikashop-api/v1/settings" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"product_contact"</span>: <span class="n">false</span>,
        <span class="k">"product_waitlist"</span>: <span class="n">false</span>,
        <span class="k">"price_with_tax"</span>: <span class="n">true</span>,
        <span class="k">"floating_tax_prices"</span>: <span class="n">false</span>,
        <span class="k">"show_original_price"</span>: <span class="n">false</span>,
        <span class="k">"round_calculations"</span>: <span class="n">0</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Change tokens for the cacheable resources

GET /version read since 6.6.0

Three opaque tokens, one for each resource worth caching. A token changes when its resource does, so a client keeps the copy it has until the token moves.

Compare them, do not read them. They are strings today and their meaning is deliberately not part of this contract.

This is what makes a dictionary of several thousand strings affordable: fetch it once, ask this cheap route afterwards.

### Response expand all

FieldTypeDescription

i18nstringMoves when the shop's translations change.

statusesstringMoves when an order status is added, renamed or unpublished.

languagesstringMoves when the shop's languages change.

```
curl "$SHOP/hikashop-api/v1/version" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"i18n"</span>: <span class="s">"1790620910"</span>,
        <span class="k">"statuses"</span>: <span class="s">"1834471105"</span>,
        <span class="k">"languages"</span>: <span class="s">"1820052638"</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## The shop's order statuses

GET /statuses read since 6.6.0

Every published order status, in the order the backend shows them. A shop invents its own, so this list is not a fixed set and should never be hard coded.

The `namekey` is the identifier to send to `POST /orders/{id}/status`; the `name` is for a person to read.

### Response a list expand all

FieldTypeDescription

namekeystringThe identifier. This is what you send when changing an order.

namestringTranslated into the operator's language, ready to display.

label\_keystringThe translation key behind that name, if you would rather translate it yourself.

colorstringThe colour the backend uses for this status, empty when none is set.

```
curl "$SHOP/hikashop-api/v1/statuses" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: [
        {
            <span class="k">"namekey"</span>: <span class="s">"created"</span>,
            <span class="k">"name"</span>: <span class="s">"created"</span>,
            <span class="k">"label_key"</span>: <span class="s">"ORDER_STATUS_CREATED"</span>,
            <span class="k">"color"</span>: <span class="s">""</span>
        },
        {
            <span class="k">"namekey"</span>: <span class="s">"confirmed"</span>,
            <span class="k">"name"</span>: <span class="s">"confirmed"</span>,
            <span class="k">"label_key"</span>: <span class="s">"ORDER_STATUS_CONFIRMED"</span>,
            <span class="k">"color"</span>: <span class="s">""</span>
        },
        {
            <span class="k">"namekey"</span>: <span class="s">"cancelled"</span>,
            <span class="k">"name"</span>: <span class="s">"cancelled"</span>,
            <span class="k">"label_key"</span>: <span class="s">"ORDER_STATUS_CANCELLED"</span>,
            <span class="k">"color"</span>: <span class="s">""</span>
        },
        {
            <span class="k">"namekey"</span>: <span class="s">"refunded"</span>,
            <span class="k">"name"</span>: <span class="s">"refunded"</span>,
            <span class="k">"label_key"</span>: <span class="s">"ORDER_STATUS_REFUNDED"</span>,
            <span class="k">"color"</span>: <span class="s">""</span>
        },
        "… 4 more, trimmed for the example"
    ],
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## HikaShop's own translation of a locale

GET /i18n read since 6.6.0

The shop's translation dictionary for one locale, so that a client can name things exactly as the merchant's own site names them, including whatever they have overridden.

It is large. Cache it against the `i18n` token from `GET /version` rather than fetching it again.

### Query

ParameterTypeDescription

localestringA HikaShop language tag such as `en-GB`. Falls back to the site language when it is not installed.

### Response expand all

FieldTypeDescription

localestringThe locale actually served, which may not be the one asked for.

stringsobjectTranslation key to translated text. Thousands of keys, and a shop can add or override any of them, so there is no list to give.

```
curl "$SHOP/hikashop-api/v1/i{id}n?locale=en-GB" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"locale"</span>: <span class="s">"en-GB"</span>,
        <span class="k">"strings"</span>: {
            <span class="k">"PRICE_BEGINNING"</span>: <span class="s">""</span>,
            <span class="k">"PRICE_BEFORE_ORIG"</span>: <span class="s">" ("</span>,
            <span class="k">"PRICE_AFTER_ORIG"</span>: <span class="s">") "</span>,
            <span class="k">"PRICE_DISCOUNT_START"</span>: <span class="s">""</span>,
            <span class="k">"PRICE_DISCOUNT_END"</span>: <span class="s">""</span>,
            <span class="k">"PRICE_BEFORE_TAX"</span>: <span class="s">" ("</span>,
            <span class="k">"PRICE_AFTER_TAX"</span>: <span class="s">" excl VAT) "</span>,
            <span class="k">"PRICE_END"</span>: <span class="s">""</span>,
            <span class="k">"FREE_PRICE"</span>: <span class="s">"Free"</span>,
            <span class="k">"PRICE_SEPARATOR"</span>: <span class="s">"<br/>"</span>,
            <span class="k">"PER_UNIT_AT_LEAST_X_BOUGHT"</span>: <span class="s">" per unit for buying at least %s"</span>,
            <span class="k">"PER_UNIT"</span>: <span class="s">" each"</span>,
            <span class="k">"ITEM_NOT_SOLD_ANYMORE"</span>: <span class="s">"Item not sold anymore"</span>,
            <span class="k">"ITEM_SOLD_ON_DATE"</span>: <span class="s">"This item will be sold starting on %s"</span>,
            <span class="k">"ADD_TO_CART"</span>: <span class="s">"Add to cart"</span>,
            <span class="k">"NO_STOCK"</span>: <span class="s">"No stock"</span>,
            <span class="k">"X_ITEMS_IN_STOCK"</span>: <span class="s">"%s items in stock"</span>,
            <span class="k">"SPECIFICATIONS"</span>: <span class="s">"Specifications"</span>,
            <span class="k">"REFRESH_INFORMATION"</span>: <span class="s">"Refresh information"</span>,
            <span class="k">"NO_VALUES_FOUND"</span>: <span class="s">"No values found"</span>,
            <span class="k">"PRODUCT"</span>: <span class="s">"Product"</span>,
            <span class="k">"CART_PRODUCT_NAME"</span>: <span class="s">"Name"</span>,
            <span class="k">"CART_PRODUCT_QUANTITY"</span>: <span class="s">"Qty"</span>,
            <span class="k">"CART_PRODUCT_PRICE"</span>: <span class="s">"Price"</span>,
            <span class="k">"CART_PRODUCT_UNIT_PRICE"</span>: <span class="s">"Unit price"</span>,
            <span class="k">"CART_PRODUCT_TOTAL_PRICE"</span>: <span class="s">"Total price"</span>,
            <span class="k">"CART_EMPTY"</span>: <span class="s">"The cart is empty"</span>,
            <span class="k">"HIKASHOP_TOTAL"</span>: <span class="s">"Total"</span>,
            <span class="k">"HIKASHOP_FINAL_TOTAL"</span>: <span class="s">"Final total"</span>,
            <span class="k">"PROCEED_TO_CHECKOUT"</span>: <span class="s">"Proceed to checkout"</span>,
            <span class="k">"REFRESH_CART"</span>: <span class="s">"Refresh cart"</span>,
            <span class="k">"PRODUCT_NOT_AVAILABLE"</span>: <span class="s">"The product %s is not available"</span>,
            <span class="k">"NOT_ENOUGH_STOCK_FOR_PRODUCT"</span>: <span class="s">"There is not enough stock for the product %s"</span>,
            <span class="k">"PRODUCT_NOT_YET_ON_SALE"</span>: <span class="s">"The product %s is not yet on sale"</span>,
            <span class="k">"PRODUCT_NOT_SOLD_ANYMORE"</span>: <span class="s">"The product %s is no longer on sale"</span>,
            <span class="k">"PRODUCT_SUCCESSFULLY_ADDED_TO_CART"</span>: <span class="s">"Product successfully added to the cart"</span>,
            <span class="k">"HIKASHOP_CHECKOUT_CART"</span>: <span class="s">"Cart"</span>,
            <span class="k">"HIKASHOP_CHECKOUT_CONFIRM"</span>: <span class="s">"Confirm"</span>,
            <span class="k">"HIKASHOP_CHECKOUT_STATUS"</span>: <span class="s">"Status"</span>,
            <span class="k">"HIKASHOP_CHECKOUT_SHIPPING"</span>: <span class="s">"Shipping"</span>,
            <span class="k">"HIKASHOP_CHECKOUT_PAYMENT"</span>: <span class="s">"Payment"</span>,
            <span class="k">"HIKASHOP_CHECKOUT_END"</span>: <span class="s">"End"</span>,
            <span class="k">"HIKASHOP_CHECKOUT_COUPON"</span>: <span class="s">"Coupon"</span>,
            <span class="k">"HIKASHOP_CHECKOUT_LOGIN"</span>: <span class="s">"Login"</span>,
            <span class="k">"HIKASHOP_CHECKOUT_ADDRESS"</span>: <span class="s">"Address"</span>,
            <span class="k">"NEXT"</span>: <span class="s">"Next"</span>,
            <span class="k">"CONTINUE_SHOPPING"</span>: <span class="s">"Continue shopping"</span>,
            <span class="k">"THANK_YOU_FOR_PURCHASE"</span>: <span class="s">"Thank you for your purchase."</span>,
            <span class="k">"ORDER_IS_COMPLETE"</span>: <span class="s">"Your order is now complete."</span>,
            <span class="k">"CURRENCY_NOT_ACCEPTED_FOR_PAYMENT"</span>: <span class="s">"The currency you selected is not accepted for payments"</span>,
            <span class="k">"PLEASE_ACCEPT_TERMS_BEFORE_FINISHING_ORDER"</span>: <span class="s">"Please accept the Terms and Conditions before proceeding"</span>,
            <span class="k">"PLEASE_ACCEPT_TERMS"</span>: <span class="s">"Please accept the Terms and Conditions before proceeding"</span>,
            <span class="k">"ADDITIONAL_INFORMATION"</span>: <span class="s">"Additional information"</span>,
            <span class="k">"LOGIN_OR_REGISTER_ACCOUNT"</span>: <span class="s">"Login or create a new account"</span>,
            <span class="k">"REGISTRATION_NOT_ALLOWED"</span>: <span class="s">"Registration not allowed"</span>,
            <span class="k">"WHEN_CLICKING_ACTIVATION"</span>: <span class="s">"Upon clicking on the activation link, your account will be activated and you will be able to continue your order"</span>,
            <span class="k">"PASSWORDS_DO_NOT_MATCH"</span>: <span class="s">"Passwords do not match"</span>,
            <span class="k">"VALID_EMAIL"</span>: <span class="s">"Please enter a valid e-mail address"</span>,
            <span class="k">"CREATE_OR_SELECT_ADDRESS"</span>: <span class="s">"Please create or select an address"</span>,
            <span class="k">"SAME_AS_BILLING"</span>: <span class="s">"Use the same address as for billing"</span>,
            <span class="k">"…"</span>: <span class="s">"4831 more keys, trimmed for the example"</span>
        }
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## The shop's languages

GET /languages read since 6.6.0

Which languages the shop publishes, and whether content translation is switched on at all.

When `enabled` is false the shop is single-language and the translation routes have nothing to do. The default language is marked and comes last, because it is the one already being edited on the main form rather than a translation of it.

### Response expand all

FieldTypeDescription

enabledbooleanWhether this shop translates its content. False on a single-language site.

languagesobject\[\]The published languages.idintegerThe language id in the shop's table.

codestringThe tag, such as `fr-FR`.

shortcodestringThe lower-case underscored form, such as `fr_fr`, which is what the translation tables key on.

site\_defaultbooleanTrue for the language the shop is written in. Its text is the original, not a translation.

```
curl "$SHOP/hikashop-api/v1/languages" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"enabled"</span>: <span class="n">true</span>,
        <span class="k">"languages"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">2</span>,
                <span class="k">"code"</span>: <span class="s">"fr-FR"</span>,
                <span class="k">"shortcode"</span>: <span class="s">"fr_fr"</span>,
                <span class="k">"site_default"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">1</span>,
                <span class="k">"code"</span>: <span class="s">"en-GB"</span>,
                <span class="k">"shortcode"</span>: <span class="s">"en_gb"</span>,
                <span class="k">"site_default"</span>: <span class="n">true</span>
            }
        ]
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Read one product

GET /products/**{id}** read since 6.6.0

Everything the product editor needs in one call: the record, its prices, its images and files, its categories, its characteristics and variants, and the definitions of the custom fields that apply to it.

Ask for a variant's id and you get the variant, with `parent_id` set. A parent's `variants` are listed in full, so you rarely need to.

### Path

ParameterTypeDescription

idrequiredintegerA parent product or a variant.

### Response expand all

FieldTypeDescription

idinteger

namestring

codestringThe SKU. Unique within the shop.

descriptionstringThe long description, as HTML.

description\_typestringWhich editor the description was written with.

publishedboolean

quantityinteger`-1` when this product does not track stock, which is not the same as `0`.

msrpnumberThe manufacturer's suggested price, shown struck through when the shop is configured to.

gtinstringThe barcode: EAN, UPC or ISBN. This is what `GET /products/lookup` matches on.

conditionstringNew, used, refurbished. Used by the feeds rather than by the shop itself.

weightnumberShipping weight, in `weight_unit`.

weight\_unitstring`kg`, `g`, `lb` or `oz`.

widthnumberIn `dimension_unit`.

heightnumberIn `dimension_unit`.

lengthnumberIn `dimension_unit`.

dimension\_unitstring`m`, `cm`, `mm`, `ft` or `in`.

min\_per\_orderintegerThe smallest quantity a customer may order, `0` for no minimum.

max\_per\_orderintegerThe largest, `0` for no maximum.

sale\_startinteger\|nullUnix timestamp before which the product is not on sale.

sale\_endinteger\|nullUnix timestamp after which it is no longer sold.

page\_titlestringSEO title, empty to use the name.

meta\_descriptionstringSEO description.

keywordsstringSEO keywords.

canonicalstringA canonical URL, when this page should point at another.

urlstringThe address of the product page on the shop.

aliasstringThe slug used in that address.

accessobjectWho may see the product: `mode` (`all`, `none` or `groups`) and `groups`, which are user \*\*group\*\* ids and not Joomla view levels. The two id spaces overlap and disagree, so a value that looks plausible can grant the wrong audience.modestring`all`, `none`, or `groups` when it is restricted to some.

groupsinteger\[\]User group ids, meaningful only when the mode is `groups`.

contactbooleanWhether this product is enquired about rather than bought.

warehouse\_idintegerThe warehouse holding the stock, `0` when the shop has none.

typestring`main` for a product, `variant` for one of its variants.

parent\_idintegerThe parent product when this is a variant, `0` otherwise.

value\_idsinteger\[\]For a variant, the characteristic values it stands for.

manufacturer\_idintegerThe brand, `0` when unset.

manufacturer\_namestringIts name, saving a second call.

tax\_idintegerThe tax category, `0` when the product is untaxed.

tax\_namestringIts name.

tax\_ratenumberThe rate as a fraction, so `0.2` is twenty percent.

pricesobject\[\]Every price row, including the restricted ones. A product with none is not sellable.idinteger

valuenumberTax excluded, as stored.

currency\_idinteger

min\_quantityintegerFrom how many items this row applies, which is how quantity breaks are expressed.

accessobjectWho this price is for, in the same shape as the product access.modestringAs above.

groupsinteger\[\]As above.

usersinteger\[\]Named customers, empty for everyone.

zone\_idsinteger\[\]Zones this price applies in, empty for everywhere.

start\_dateinteger\|nullUnix timestamp.

end\_dateinteger\|nullUnix timestamp.

imagesobject\[\]In the order the editor shows them; the first is the main image.idinteger

namestring

pathstringRelative to the upload folder.

urlstringAbsolute, ready to display.

orderinginteger

descriptionstringThe alt text.

accessobjectWho may see it.modestringAs above.

groupsinteger\[\]As above.

free\_downloadbooleanFiles only; meaningless on an image.

filesobject\[\]Downloadable files, in the same shape as the images.idinteger

namestring

pathstringRelative to the upload folder.

urlstringAbsolute.

orderinginteger

descriptionstring

accessobjectWho may download it.

free\_downloadbooleanWhether it can be downloaded without buying the product.

categoriesobject\[\]The categories the product is in.idinteger

namestring

bundleobject\[\]The products this one is made of, when it is a bundle.idinteger

namestring

codestring

quantityintegerHow many of it the bundle contains.

optionsobject\[\]Products offered as options alongside this one.idinteger

namestring

codestring

quantityinteger

relatedobject\[\]Products shown as related.idinteger

namestring

codestring

quantityinteger

tagsinteger\[\]CMS tag ids.

characteristicsobject\[\]The characteristics this product varies on. Empty when it has no variants.idintegerThe characteristic, such as Size.

namestringIts name.

valuesobject\[\]The values of it this product uses, such as S, M and L.idintegerThe value id, which is what a variant refers to.

valuestringIts name, such as `M`.

variantsobject\[\]Every variant, with its own code, stock, price and images. Empty for a product that does not vary.idintegerThe variant is a product in its own right, and this is its id.

codestringIts own SKU.

quantityintegerIts own stock. This is the figure to change, not the parent's.

publishedboolean

pricenumber\|null`null` when the variant has no price of its own and the parent's applies.

valuesobject\[\]Which characteristic values this variant stands for, one per characteristic.option\_idintegerThe characteristic.

option\_namestringIts name, so the variant can be labelled without a second call.

value\_idintegerThe value.

valuestringIts name.

imagesobject\[\]The variant's own images, in the same shape as the product's.idinteger

namestring

pathstringRelative to the upload folder.

urlstringAbsolute.

orderinginteger

fieldsobject\[\]The definitions of the custom fields that apply to this product, so a client can build a form for them.namekeystringThe key used in `custom_fields`.

typestring`text`, `radio`, `singledropdown`, `file`, and the rest of HikaShop's field types.

raw\_typestringHikaShop's own name for the type, before it is mapped to something a client can render.

labelstringTranslated into the operator's language.

defaultstringThe value used when none is given.

requiredbooleanWhether the shop refuses to save the product without it.

optionsobject\[\]The choices, for a field that has them. Empty for a free text one.

multiplebooleanWhether more than one choice may be selected.

translatablebooleanWhether its value can be translated, which is what the translation routes offer.

upload\_dirstringFor a file field, where its uploads are kept.

allowed\_extensionsstringFor a file field, the extensions it accepts, comma separated. Empty means the shop default.

date\_formatstringFor a date field, the format it is stored in.

custom\_fieldsobjectTheir values, keyed by namekey. The keys are whatever this shop has configured; `fields` in the same response says what they are.

custom\_field\_filesobjectFor custom fields holding a file, the file behind each value. Keyed the same way.

sectionsobject\[\]Information other plugins show on this record, each with a `key`, a `title` and `rows` (`label`, `value`, and optionally `url`, `badge` and `ref`). Empty when no plugin adds any; on a customer, core adds their paid downloads. See the guide on adding information and settings.

extensionsobject\[\]Settings other plugins keep on this record, in groups (`key`, `title`, `fields`), each field described like a custom field plus its current `value`. Send changes back as `extensions` with the record's save. Empty when no plugin adds any.

```
curl "$SHOP/hikashop-api/v1/products/{id}" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">8661</span>,
        <span class="k">"name"</span>: <span class="s">"Full-Grain Sneakers"</span>,
        <span class="k">"code"</span>: <span class="s">"DEMO-0023"</span>,
        <span class="k">"description"</span>: <span class="s">"Our best-selling sneakers. Back in stock, and worth the wait."</span>,
        <span class="k">"description_type"</span>: <span class="s">""</span>,
        <span class="k">"published"</span>: <span class="n">true</span>,
        <span class="k">"quantity"</span>: <span class="n">0</span>,
        <span class="k">"msrp"</span>: <span class="n">0</span>,
        <span class="k">"gtin"</span>: <span class="s">""</span>,
        <span class="k">"condition"</span>: <span class="s">""</span>,
        <span class="k">"weight"</span>: <span class="n">0.213</span>,
        <span class="k">"weight_unit"</span>: <span class="s">"kg"</span>,
        <span class="k">"width"</span>: <span class="n">0</span>,
        <span class="k">"height"</span>: <span class="n">0</span>,
        <span class="k">"length"</span>: <span class="n">0</span>,
        <span class="k">"dimension_unit"</span>: <span class="s">"m"</span>,
        <span class="k">"min_per_order"</span>: <span class="n">0</span>,
        <span class="k">"max_per_order"</span>: <span class="n">0</span>,
        <span class="k">"sale_start"</span>: <span class="n">0</span>,
        <span class="k">"sale_end"</span>: <span class="n">0</span>,
        <span class="k">"page_title"</span>: <span class="s">""</span>,
        <span class="k">"meta_description"</span>: <span class="s">""</span>,
        <span class="k">"keywords"</span>: <span class="s">""</span>,
        <span class="k">"canonical"</span>: <span class="s">""</span>,
        <span class="k">"url"</span>: <span class="s">""</span>,
        <span class="k">"alias"</span>: <span class="s">""</span>,
        <span class="k">"access"</span>: {
            <span class="k">"mode"</span>: <span class="s">"all"</span>,
            <span class="k">"groups"</span>: []
        },
        <span class="k">"contact"</span>: <span class="n">false</span>,
        <span class="k">"warehouse_id"</span>: <span class="n">0</span>,
        <span class="k">"type"</span>: <span class="s">"main"</span>,
        <span class="k">"parent_id"</span>: <span class="n">0</span>,
        <span class="k">"value_ids"</span>: [],
        <span class="k">"manufacturer_id"</span>: <span class="n">0</span>,
        <span class="k">"manufacturer_name"</span>: <span class="s">""</span>,
        <span class="k">"tax_id"</span>: <span class="n">0</span>,
        <span class="k">"tax_name"</span>: <span class="s">""</span>,
        <span class="k">"tax_rate"</span>: <span class="n">0</span>,
        <span class="k">"prices"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">4652</span>,
                <span class="k">"value"</span>: <span class="n">308.3</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>,
                <span class="k">"min_quantity"</span>: <span class="n">0</span>,
                <span class="k">"access"</span>: {
                    <span class="k">"mode"</span>: <span class="s">"all"</span>,
                    <span class="k">"groups"</span>: []
                },
                <span class="k">"users"</span>: [],
                <span class="k">"zone_ids"</span>: [],
                <span class="k">"start_date"</span>: <span class="n">0</span>,
                <span class="k">"end_date"</span>: <span class="n">0</span>
            }
        ],
        <span class="k">"images"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">7791</span>,
                <span class="k">"name"</span>: <span class="s">"Full-Grain Sneakers"</span>,
                <span class="k">"path"</span>: <span class="s">"demo-0023.png"</span>,
                <span class="k">"url"</span>: <span class="s">"http://localhost:<span class="n">8080</span>/joomla6_ext/images/com_hikashop/upload/demo-0023.png"</span>,
                <span class="k">"ordering"</span>: <span class="n">1</span>,
                <span class="k">"description"</span>: <span class="s">""</span>,
                <span class="k">"access"</span>: {
                    <span class="k">"mode"</span>: <span class="s">"all"</span>,
                    <span class="k">"groups"</span>: []
                },
                <span class="k">"free_download"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">7792</span>,
                <span class="k">"name"</span>: <span class="s">"Full-Grain Sneakers"</span>,
                <span class="k">"path"</span>: <span class="s">"demo-0023-2.png"</span>,
                <span class="k">"url"</span>: <span class="s">"http://localhost:<span class="n">8080</span>/joomla6_ext/images/com_hikashop/upload/demo-0023-2.png"</span>,
                <span class="k">"ordering"</span>: <span class="n">2</span>,
                <span class="k">"description"</span>: <span class="s">""</span>,
                <span class="k">"access"</span>: {
                    <span class="k">"mode"</span>: <span class="s">"all"</span>,
                    <span class="k">"groups"</span>: []
                },
                <span class="k">"free_download"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">7793</span>,
                <span class="k">"name"</span>: <span class="s">"Full-Grain Sneakers"</span>,
                <span class="k">"path"</span>: <span class="s">"demo-0023-3.png"</span>,
                <span class="k">"url"</span>: <span class="s">"http://localhost:<span class="n">8080</span>/joomla6_ext/images/com_hikashop/upload/demo-0023-3.png"</span>,
                <span class="k">"ordering"</span>: <span class="n">3</span>,
                <span class="k">"description"</span>: <span class="s">""</span>,
                <span class="k">"access"</span>: {
                    <span class="k">"mode"</span>: <span class="s">"all"</span>,
                    <span class="k">"groups"</span>: []
                },
                <span class="k">"free_download"</span>: <span class="n">false</span>
            }
        ],
        <span class="k">"files"</span>: [],
        <span class="k">"categories"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">238</span>,
                <span class="k">"name"</span>: <span class="s">"Shoes"</span>
            }
        ],
        <span class="k">"bundle"</span>: [],
        <span class="k">"options"</span>: [],
        <span class="k">"related"</span>: [],
        <span class="k">"tags"</span>: [],
        <span class="k">"characteristics"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">8</span>,
                <span class="k">"name"</span>: <span class="s">"Size"</span>,
                <span class="k">"values"</span>: [
                    {
                        <span class="k">"id"</span>: <span class="n">9</span>,
                        <span class="k">"value"</span>: <span class="s">"S"</span>
                    },
                    {
                        <span class="k">"id"</span>: <span class="n">10</span>,
                        <span class="k">"value"</span>: <span class="s">"L"</span>
                    },
                    {
                        <span class="k">"id"</span>: <span class="n">21</span>,
                        <span class="k">"value"</span>: <span class="s">"M"</span>
                    },
                    {
                        <span class="k">"id"</span>: <span class="n">35</span>,
                        <span class="k">"value"</span>: <span class="s">"XS"</span>
                    },
                    "… 1 more, trimmed for the example"
                ]
            }
        ],
        <span class="k">"variants"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">8662</span>,
                <span class="k">"code"</span>: <span class="s">"DEMO-0023-XS"</span>,
                <span class="k">"quantity"</span>: <span class="n">1</span>,
                <span class="k">"published"</span>: <span class="n">true</span>,
                <span class="k">"price"</span>: <span class="n">null</span>,
                <span class="k">"values"</span>: [
                    {
                        <span class="k">"option_id"</span>: <span class="n">8</span>,
                        <span class="k">"option_name"</span>: <span class="s">"Size"</span>,
                        <span class="k">"value_id"</span>: <span class="n">35</span>,
                        <span class="k">"value"</span>: <span class="s">"XS"</span>
                    }
                ],
                <span class="k">"images"</span>: [
                    {
                        <span class="k">"id"</span>: <span class="n">7794</span>,
                        <span class="k">"name"</span>: <span class="s">"Full-Grain Sneakers — XS"</span>,
                        <span class="k">"path"</span>: <span class="s">"demo-0023-xs.png"</span>,
                        <span class="k">"url"</span>: <span class="s">"http://localhost:<span class="n">8080</span>/joomla6_ext/images/com_hikashop/upload/demo-0023-xs.png"</span>,
                        <span class="k">"ordering"</span>: <span class="n">1</span>
                    }
                ]
            },
            {
                <span class="k">"id"</span>: <span class="n">8663</span>,
                <span class="k">"code"</span>: <span class="s">"DEMO-0023-S"</span>,
                <span class="k">"quantity"</span>: <span class="n">23</span>,
                <span class="k">"published"</span>: <span class="n">true</span>,
                <span class="k">"price"</span>: <span class="n">null</span>,
                <span class="k">"values"</span>: [
                    {
                        <span class="k">"option_id"</span>: <span class="n">8</span>,
                        <span class="k">"option_name"</span>: <span class="s">"Size"</span>,
                        <span class="k">"value_id"</span>: <span class="n">9</span>,
                        <span class="k">"value"</span>: <span class="s">"S"</span>
                    }
                ],
                <span class="k">"images"</span>: [
                    {
                        <span class="k">"id"</span>: <span class="n">7795</span>,
                        <span class="k">"name"</span>: <span class="s">"Full-Grain Sneakers — S"</span>,
                        <span class="k">"path"</span>: <span class="s">"demo-0023-s.png"</span>,
                        <span class="k">"url"</span>: <span class="s">"http://localhost:<span class="n">8080</span>/joomla6_ext/images/com_hikashop/upload/demo-0023-s.png"</span>,
                        <span class="k">"ordering"</span>: <span class="n">1</span>
                    }
                ]
            },
            {
                <span class="k">"id"</span>: <span class="n">8664</span>,
                <span class="k">"code"</span>: <span class="s">"DEMO-0023-M"</span>,
                <span class="k">"quantity"</span>: <span class="n">40</span>,
                <span class="k">"published"</span>: <span class="n">true</span>,
                <span class="k">"price"</span>: <span class="n">null</span>,
                <span class="k">"values"</span>: [
                    {
                        <span class="k">"option_id"</span>: <span class="n">8</span>,
                        <span class="k">"option_name"</span>: <span class="s">"Size"</span>,
                        <span class="k">"value_id"</span>: <span class="n">21</span>,
                        <span class="k">"value"</span>: <span class="s">"M"</span>
                    }
                ],
                <span class="k">"images"</span>: [
                    {
                        <span class="k">"id"</span>: <span class="n">7796</span>,
                        <span class="k">"name"</span>: <span class="s">"Full-Grain Sneakers — M"</span>,
                        <span class="k">"path"</span>: <span class="s">"demo-0023-m.png"</span>,
                        <span class="k">"url"</span>: <span class="s">"http://localhost:<span class="n">8080</span>/joomla6_ext/images/com_hikashop/upload/demo-0023-m.png"</span>,
                        <span class="k">"ordering"</span>: <span class="n">1</span>
                    }
                ]
            },
            {
                <span class="k">"id"</span>: <span class="n">8665</span>,
                <span class="k">"code"</span>: <span class="s">"DEMO-0023-L"</span>,
                <span class="k">"quantity"</span>: <span class="n">38</span>,
                <span class="k">"published"</span>: <span class="n">true</span>,
                <span class="k">"price"</span>: <span class="n">null</span>,
                <span class="k">"values"</span>: [
                    {
                        <span class="k">"option_id"</span>: <span class="n">8</span>,
                        <span class="k">"option_name"</span>: <span class="s">"Size"</span>,
                        <span class="k">"value_id"</span>: <span class="n">10</span>,
                        <span class="k">"value"</span>: <span class="s">"L"</span>
                    }
                ],
                <span class="k">"images"</span>: [
                    {
                        <span class="k">"id"</span>: <span class="n">7797</span>,
                        <span class="k">"name"</span>: <span class="s">"Full-Grain Sneakers — L"</span>,
                        <span class="k">"path"</span>: <span class="s">"demo-0023-l.png"</span>,
                        <span class="k">"url"</span>: <span class="s">"http://localhost:<span class="n">8080</span>/joomla6_ext/images/com_hikashop/upload/demo-0023-l.png"</span>,
                        <span class="k">"ordering"</span>: <span class="n">1</span>
                    }
                ]
            },
            "… 1 more, trimmed for the example"
        ],
        <span class="k">"fields"</span>: [
            {
                <span class="k">"namekey"</span>: <span class="s">"test_ajax_image"</span>,
                <span class="k">"type"</span>: <span class="s">"ajaximage"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"ajaximage"</span>,
                <span class="k">"label"</span>: <span class="s">"Test Ajax Image"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">false</span>,
                <span class="k">"options"</span>: [],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">"%Y-%m-%d"</span>
            },
            {
                <span class="k">"namekey"</span>: <span class="s">"product_gtin"</span>,
                <span class="k">"type"</span>: <span class="s">"text"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"text"</span>,
                <span class="k">"label"</span>: <span class="s">"GTIN"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">false</span>,
                <span class="k">"options"</span>: [],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            }
        ],
        <span class="k">"custom_fields"</span>: {
            <span class="k">"test_ajax_image"</span>: <span class="n">null</span>,
            <span class="k">"product_gtin"</span>: <span class="n">null</span>
        },
        <span class="k">"custom_field_files"</span>: {
            <span class="k">"test_ajax_image"</span>: []
        },
        <span class="k">"sections"</span>: [],
        <span class="k">"extensions"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Resolve a scanned barcode

GET /products/lookup read since 6.6.0

One product from one barcode, for a scanner. It matches the product code and the GTIN, and it looks at variants as well as parents, because the thing with a barcode on it is usually the variant.

Exactly one product comes back, or `not_found`. It is deliberately not a search: a scanner needs an answer, not a list.

### Query

ParameterTypeDescription

barcoderequiredstringWhat the scanner read. Matched against the product code and the GTIN.

### Response expand all

FieldTypeDescription

idintegerThe product to open. For a variant, this is its parent.

variant\_idintegerThe variant that was scanned, `0` when the barcode belonged to the parent.

namestring

codestringThe SKU that matched.

gtinstringThe barcode held on the record, which may differ in leading zeros from what was scanned.

quantityintegerThe stock of whichever record matched, so a stock take needs no second call.

### Errors

CodeHTTPMeans

missing\_barcode400No barcode was given.

not\_found404Nothing in the shop carries that code.

```
curl "$SHOP/hikashop-api/v1/products/lookup?barcode=TEST{id}" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">1</span>,
        <span class="k">"variant_id"</span>: <span class="n">0</span>,
        <span class="k">"name"</span>: <span class="s">"Test Product (Vendor 2)"</span>,
        <span class="k">"code"</span>: <span class="s">"TEST001"</span>,
        <span class="k">"gtin"</span>: <span class="s">""</span>,
        <span class="k">"quantity"</span>: <span class="n">-1</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Products running out

GET /products/low-stock read since 6.6.0

Sellable items at or below a stock threshold, cheapest first to reorder. Variants are listed in their own right, since that is where the stock actually sits.

Products that do not track stock are left out: they are not running out of anything.

### Query

ParameterTypeDescription

thresholdintegerAt or below which a product counts as low. Defaults to `5`.

limitintegerDefaults to `20`, capped at `100`.

### Response a list expand all

FieldTypeDescription

idintegerThe parent product.

variant\_idintegerThe variant that is low, `0` when the parent itself is.

namestring

codestringThe SKU of whichever record is low.

quantityintegerWhat is left.

```
curl "$SHOP/hikashop-api/v1/products/low-stock?threshold={id}&limit=3" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: [
        {
            <span class="k">"id"</span>: <span class="n">8657</span>,
            <span class="k">"variant_id"</span>: <span class="n">0</span>,
            <span class="k">"name"</span>: <span class="s">"Botanical Shampoo Bottle — 500 ml"</span>,
            <span class="k">"code"</span>: <span class="s">"DEMO-0019"</span>,
            <span class="k">"quantity"</span>: <span class="n">0</span>
        },
        {
            <span class="k">"id"</span>: <span class="n">8896</span>,
            <span class="k">"variant_id"</span>: <span class="n">0</span>,
            <span class="k">"name"</span>: <span class="s">"Brass Colored Pencils — 12"</span>,
            <span class="k">"code"</span>: <span class="s">"DEMO-0193"</span>,
            <span class="k">"quantity"</span>: <span class="n">0</span>
        },
        {
            <span class="k">"id"</span>: <span class="n">9007</span>,
            <span class="k">"variant_id"</span>: <span class="n">0</span>,
            <span class="k">"name"</span>: <span class="s">"Brass Colored Pencils — 36"</span>,
            <span class="k">"code"</span>: <span class="s">"DEMO-0279"</span>,
            <span class="k">"quantity"</span>: <span class="n">0</span>
        }
    ],
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Set a product's stock

POST /products/**{id}**/stock write since 6.6.0

Sets the tracked quantity to an absolute figure, which is what a stock take does. It is not an adjustment: send what the shelf holds, not the difference.

A product with variants keeps no stock of its own, so set it on the variant instead. Asking to set it on the parent is refused rather than silently ignored.

### Path

ParameterTypeDescription

idrequiredintegerThe product or variant to set.

### Body

FieldTypeDescription

quantityrequiredintegerThe new absolute quantity. `-1` turns stock tracking off for this product.

### Response expand all

FieldTypeDescription

idinteger

quantityintegerAs stored, so you can confirm what was written.

### Errors

CodeHTTPMeans

not\_found404No such product, or the operator may not change it.

has\_variants409It is a parent: set the stock on one of its variants.

```
curl -X POST "$SHOP/hikashop-api/v1/products/2/stock" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "quantity": 42
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">2</span>,
        <span class="k">"quantity"</span>: <span class="n">42</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## List customers

GET /customers read since 6.6.0

The customers the operator may see, with enough to recognise one and to know whether they have bought anything.

Guests are included. A shop that lets people order without an account still has a row for each of them, and `type` is how you tell the two apart.

### Query

ParameterTypeDescription

startintegerOffset. Defaults to `0`.

limitintegerDefaults to `20`, capped at `100`.

searchstringMatches the email address, the account name and login, and the first name and surname on any of their addresses, including the two together, so `John Doe` finds a guest who has never had an account.

emailstringThe exact email address, ignoring case: one customer or none. For a client that knows who it is looking for, such as a helpdesk matching a message to its sender, where `search` would also find `<joomla-hidden-mail base="" first="YW5uZQ==" is-email="1" is-link="1" last="c2hvcC5jb20=" text="YW5uZUBzaG9wLmNvbQ==">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>` for `<joomla-hidden-mail base="" first="YW5u" is-email="1" is-link="1" last="c2hvcC5jb20=" text="YW5uQHNob3AuY29t">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>`.

### Response a list expand all

FieldTypeDescription

idintegerThe HikaShop customer id, which is not the CMS user id.

namestringThe account name, or for a guest the name on their default address, since a guest has no account to take one from.

emailstring

typestring`registered` for an account, `guest` for someone who ordered without one.

createdintegerUnix timestamp of the first time the shop saw them.

order\_countintegerHow many orders they have placed, so a list can be sorted by worth without a second call.

### Envelope meta

FieldTypeDescription

startintegerEchoes the offset used.

limitintegerEchoes the page size used.

totalintegerCustomers matching the filter, before paging.

```
curl "$SHOP/hikashop-api/v1/customers?limit=2" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: [
        {
            <span class="k">"id"</span>: <span class="n">5424</span>,
            <span class="k">"name"</span>: <span class="s">"Alex Marchand"</span>,
            <span class="k">"email"</span>: <span class="s">"<joomla-hidden-mail base="" first="YnV5ZXI=" is-email="1" is-link="1" last="ZXhhbXBsZS50ZXN0" text="YnV5ZXJAZXhhbXBsZS50ZXN0">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>"</span>,
            <span class="k">"type"</span>: <span class="s">"guest"</span>,
            <span class="k">"created"</span>: <span class="n">1790620906</span>,
            <span class="k">"order_count"</span>: <span class="n">0</span>
        },
        {
            <span class="k">"id"</span>: <span class="n">5412</span>,
            <span class="k">"name"</span>: <span class="s">""</span>,
            <span class="k">"email"</span>: <span class="s">"<joomla-hidden-mail base="" first="YnV5ZXI=" is-email="1" is-link="1" last="ZXhhbXBsZS50ZXN0" text="YnV5ZXJAZXhhbXBsZS50ZXN0">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>"</span>,
            <span class="k">"type"</span>: <span class="s">"guest"</span>,
            <span class="k">"created"</span>: <span class="n">1789923608</span>,
            <span class="k">"order_count"</span>: <span class="n">0</span>
        }
    ],
    <span class="k">"meta"</span>: {
        <span class="k">"start"</span>: <span class="n">0</span>,
        <span class="k">"limit"</span>: <span class="n">2</span>,
        <span class="k">"total"</span>: <span class="n">384</span>
    },
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## List discounts and coupons

GET /discounts read since 6.6.0

Both kinds of reduction live in one table and are told apart by `type`: a **discount** applies by itself when its conditions are met, a **coupon** waits for its code to be entered.

The restriction fields are the interesting part, and they are all lists of ids: which products, which categories, which zones, which customers, and the same again for exclusions. An empty list means no restriction of that kind rather than none allowed.

### Query

ParameterTypeDescription

startintegerOffset. Defaults to `0`.

limitintegerDefaults to `20`, capped at `100`.

typestring`discount` or `coupon`, to list one kind.

searchstringMatches the code.

### Response a list expand all

FieldTypeDescription

idinteger

typestring`discount` applies by itself, `coupon` waits for its code.

codestringWhat the customer types. Empty on a discount.

kindstringWhether the value is a percentage or a fixed amount.

valuenumberThe reduction, read according to `kind`.

currency\_idintegerThe currency a fixed amount is in.

publishedboolean

startinteger\|nullUnix timestamp before which it does not apply.

endinteger\|nullUnix timestamp after which it expires.

minimum\_ordernumberOrder total below which it does not apply, `0` for none.

maximum\_ordernumberOrder total above which it stops applying, `0` for none.

quotaintegerHow many times it may be used in total, `0` for no limit.

quota\_per\_userintegerHow many times one customer may use it, `0` for no limit.

used\_timesintegerHow many times it already has been.

tax\_includedbooleanWhether the value is understood as tax included.

tax\_idintegerThe tax category of the reduction itself.

shipping\_percentnumberA reduction on the shipping rather than on the goods.

minimum\_productsintegerFewest items in the cart for it to apply.

maximum\_productsintegerMost items for it to still apply.

product\_idsinteger\[\]Restricted to these products. Empty means all of them.

exclude\_product\_idsinteger\[\]Never applies to these.

category\_idsinteger\[\]Restricted to these categories.

category\_childsbooleanWhether those categories include their sub-categories.

exclude\_category\_idsinteger\[\]Never applies in these categories.

exclude\_category\_childsbooleanWhether those exclusions include sub-categories.

zone\_idsinteger\[\]Restricted to these zones.

user\_idsinteger\[\]Restricted to these customers.

accessobjectWhich user groups it is for, in the usual `mode` and `groups` shape.modestring`all`, `none`, or `groups` when it is restricted to some.

groupsinteger\[\]User \*\*group\*\* ids, and not Joomla view levels. The two id spaces overlap and disagree, so a value that looks plausible can grant the wrong audience.

exclude\_accessobjectWhich user groups it is never for.modestring`all`, `none`, or `groups` when it is restricted to some.

groupsinteger\[\]User \*\*group\*\* ids, and not Joomla view levels. The two id spaces overlap and disagree, so a value that looks plausible can grant the wrong audience.

auto\_loadbooleanFor a coupon, whether the shop applies it without the customer typing it.

product\_onlybooleanWhether it reduces only the goods and leaves the fees alone.

discounted\_productsintegerHow many products in the cart it applied to, on a discount that has been used.

### Envelope meta

FieldTypeDescription

startintegerEchoes the offset used.

limitintegerEchoes the page size used.

totalintegerRows matching the filter, before paging.

```
curl "$SHOP/hikashop-api/v1/discounts?limit=2" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: [
        {
            <span class="k">"id"</span>: <span class="n">435</span>,
            <span class="k">"type"</span>: <span class="s">"discount"</span>,
            <span class="k">"code"</span>: <span class="s">"auto-2"</span>,
            <span class="k">"kind"</span>: <span class="s">"percent"</span>,
            <span class="k">"value"</span>: <span class="n">9</span>,
            <span class="k">"currency_id"</span>: <span class="n">0</span>,
            <span class="k">"published"</span>: <span class="n">true</span>,
            <span class="k">"start"</span>: <span class="n">0</span>,
            <span class="k">"end"</span>: <span class="n">0</span>,
            <span class="k">"minimum_order"</span>: <span class="n">0</span>,
            <span class="k">"maximum_order"</span>: <span class="n">0</span>,
            <span class="k">"quota"</span>: <span class="n">0</span>,
            <span class="k">"quota_per_user"</span>: <span class="n">0</span>,
            <span class="k">"used_times"</span>: <span class="n">5</span>,
            <span class="k">"tax_included"</span>: <span class="n">false</span>,
            <span class="k">"tax_id"</span>: <span class="n">0</span>,
            <span class="k">"shipping_percent"</span>: <span class="n">0</span>,
            <span class="k">"minimum_products"</span>: <span class="n">0</span>,
            <span class="k">"maximum_products"</span>: <span class="n">0</span>,
            <span class="k">"product_ids"</span>: [],
            <span class="k">"exclude_product_ids"</span>: [],
            <span class="k">"category_ids"</span>: [],
            <span class="k">"category_childs"</span>: <span class="n">false</span>,
            <span class="k">"exclude_category_ids"</span>: [],
            <span class="k">"exclude_category_childs"</span>: <span class="n">false</span>,
            <span class="k">"zone_ids"</span>: [],
            <span class="k">"user_ids"</span>: [],
            <span class="k">"access"</span>: {
                <span class="k">"mode"</span>: <span class="s">"all"</span>,
                <span class="k">"groups"</span>: []
            },
            <span class="k">"exclude_access"</span>: {
                <span class="k">"mode"</span>: <span class="s">"none"</span>,
                <span class="k">"groups"</span>: []
            },
            <span class="k">"auto_load"</span>: <span class="n">false</span>,
            <span class="k">"product_only"</span>: <span class="n">false</span>,
            <span class="k">"discounted_products"</span>: <span class="n">0</span>
        },
        {
            <span class="k">"id"</span>: <span class="n">434</span>,
            <span class="k">"type"</span>: <span class="s">"coupon"</span>,
            <span class="k">"code"</span>: <span class="s">"E2E1786215747620"</span>,
            <span class="k">"kind"</span>: <span class="s">"percent"</span>,
            <span class="k">"value"</span>: <span class="n">12</span>,
            <span class="k">"currency_id"</span>: <span class="n">0</span>,
            <span class="k">"published"</span>: <span class="n">true</span>,
            <span class="k">"start"</span>: <span class="n">0</span>,
            <span class="k">"end"</span>: <span class="n">0</span>,
            <span class="k">"minimum_order"</span>: <span class="n">0</span>,
            <span class="k">"maximum_order"</span>: <span class="n">0</span>,
            <span class="k">"quota"</span>: <span class="n">0</span>,
            <span class="k">"quota_per_user"</span>: <span class="n">0</span>,
            <span class="k">"used_times"</span>: <span class="n">0</span>,
            <span class="k">"tax_included"</span>: <span class="n">false</span>,
            <span class="k">"tax_id"</span>: <span class="n">0</span>,
            <span class="k">"shipping_percent"</span>: <span class="n">0</span>,
            <span class="k">"minimum_products"</span>: <span class="n">0</span>,
            <span class="k">"maximum_products"</span>: <span class="n">0</span>,
            <span class="k">"product_ids"</span>: [],
            <span class="k">"exclude_product_ids"</span>: [],
            <span class="k">"category_ids"</span>: [],
            <span class="k">"category_childs"</span>: <span class="n">false</span>,
            <span class="k">"exclude_category_ids"</span>: [],
            <span class="k">"exclude_category_childs"</span>: <span class="n">false</span>,
            <span class="k">"zone_ids"</span>: [],
            <span class="k">"user_ids"</span>: [],
            <span class="k">"access"</span>: {
                <span class="k">"mode"</span>: <span class="s">"all"</span>,
                <span class="k">"groups"</span>: []
            },
            <span class="k">"exclude_access"</span>: {
                <span class="k">"mode"</span>: <span class="s">"none"</span>,
                <span class="k">"groups"</span>: []
            },
            <span class="k">"auto_load"</span>: <span class="n">false</span>,
            <span class="k">"product_only"</span>: <span class="n">false</span>,
            <span class="k">"discounted_products"</span>: <span class="n">0</span>
        }
    ],
    <span class="k">"meta"</span>: {
        <span class="k">"start"</span>: <span class="n">0</span>,
        <span class="k">"limit"</span>: <span class="n">2</span>,
        <span class="k">"total"</span>: <span class="n">5</span>
    },
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## The category tree

GET /categories read since 6.6.0

One level of the category tree at a time, unpublished categories included, which is what makes this a management view rather than a shop one.

Pass a `parent_id` to walk down. `has_children` tells you whether there is anything below without asking, so a tree can be drawn lazily.

HikaShop keeps its manufacturers and its tax categories in the same table as the product categories, told apart by their root. Ask for the tree you want.

### Query

ParameterTypeDescription

parent\_idintegerWhose children to list. Omit for the top level.

startintegerOffset. Defaults to `0`.

limitintegerDefaults to `20`, capped at `100`.

searchstringMatches the name, across the whole tree rather than one level.

### Response a list expand all

FieldTypeDescription

idinteger

namestring

parent\_idintegerIts parent, so a flat answer can be rebuilt into a tree.

publishedboolean

has\_childrenbooleanWhether anything sits below it.

imagestring\|nullAbsolute URL of its image, `null` when it has none.

### Envelope meta

FieldTypeDescription

totalintegerCategories matching, before paging.

startintegerEchoes the offset used.

limitintegerEchoes the page size used.

```
curl "$SHOP/hikashop-api/v1/categories?limit=3" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: [
        {
            <span class="k">"id"</span>: <span class="n">17</span>,
            <span class="k">"name"</span>: <span class="s">"Unrelated Cat"</span>,
            <span class="k">"parent_id"</span>: <span class="n">2</span>,
            <span class="k">"published"</span>: <span class="n">true</span>,
            <span class="k">"has_children"</span>: <span class="n">false</span>,
            <span class="k">"image"</span>: <span class="s">""</span>
        },
        {
            <span class="k">"id"</span>: <span class="n">18</span>,
            <span class="k">"name"</span>: <span class="s">"StoreLinkr Cat"</span>,
            <span class="k">"parent_id"</span>: <span class="n">2</span>,
            <span class="k">"published"</span>: <span class="n">true</span>,
            <span class="k">"has_children"</span>: <span class="n">true</span>,
            <span class="k">"image"</span>: <span class="s">""</span>
        },
        {
            <span class="k">"id"</span>: <span class="n">20</span>,
            <span class="k">"name"</span>: <span class="s">"Via Ajax Cat"</span>,
            <span class="k">"parent_id"</span>: <span class="n">2</span>,
            <span class="k">"published"</span>: <span class="n">true</span>,
            <span class="k">"has_children"</span>: <span class="n">false</span>,
            <span class="k">"image"</span>: <span class="s">""</span>
        }
    ],
    <span class="k">"meta"</span>: {
        <span class="k">"total"</span>: <span class="n">20</span>,
        <span class="k">"start"</span>: <span class="n">0</span>,
        <span class="k">"limit"</span>: <span class="n">3</span>
    },
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Read one category

GET /categories/**{id}** read since 6.6.0

A category with its description, its image, who may see it, and your own category fields.

### Path

ParameterTypeDescription

idrequiredintegerThe category id.

### Response expand all

FieldTypeDescription

fieldsobject\[\]The definitions of your own category fields.

idinteger

namestring

parent\_idintegerIts parent.

typestringWhich tree it belongs to: `product`, `manufacturer`, `tax`, and so on.

descriptionstringThe long description, as HTML.

meta\_descriptionstringSEO description.

publishedboolean

accessobjectWho may see it.modestring`all`, `none`, or `groups` when it is restricted to some.

groupsinteger\[\]User \*\*group\*\* ids, and not Joomla view levels. The two id spaces overlap and disagree, so a value that looks plausible can grant the wrong audience.

imagestring\|nullAbsolute URL of its image, `null` when it has none.

custom\_fieldsobjectTheir values, keyed by namekey. The keys depend on the shop; `fields` says what they are.

custom\_field\_filesobjectFor a field holding a file, the file behind the value. Keyed the same way.

```
curl "$SHOP/hikashop-api/v1/categories/2" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"fields"</span>: [],
        <span class="k">"id"</span>: <span class="n">2</span>,
        <span class="k">"name"</span>: <span class="s">"product category"</span>,
        <span class="k">"parent_id"</span>: <span class="n">1</span>,
        <span class="k">"type"</span>: <span class="s">"product"</span>,
        <span class="k">"description"</span>: <span class="s">""</span>,
        <span class="k">"meta_description"</span>: <span class="s">""</span>,
        <span class="k">"published"</span>: <span class="n">true</span>,
        <span class="k">"access"</span>: {
            <span class="k">"mode"</span>: <span class="s">"all"</span>,
            <span class="k">"groups"</span>: []
        },
        <span class="k">"image"</span>: <span class="s">""</span>,
        <span class="k">"custom_fields"</span>: [],
        <span class="k">"custom_field_files"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## The shop's own bulk operations

GET /massactions read since 6.6.0

The mass actions the merchant has configured for a listing, so a client can offer the merchant's own bulk operations rather than a fixed set of its own.

Whatever they built in the backend appears here, and running one is `POST /massactions/{id}`.

### Query

ParameterTypeDescription

tablerequiredstringWhich listing: `product`, `order`, `user`, `category`, `address`.

### Response a list expand all

FieldTypeDescription

idintegerWhat to run.

namestringAs the merchant named it.

descriptionstringTheir own note about what it does, when they wrote one.

tablestringThe listing it belongs to.

restrictedbooleanWhether it may only run on a selection rather than on everything matching a filter.

### Errors

CodeHTTPMeans

invalid\_request400The table is not one the shop has mass actions for.

forbidden403The operator may not view that kind of record.

```
curl "$SHOP/hikashop-api/v1/massactions?table=product" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: [
        {
            <span class="k">"id"</span>: <span class="n">2</span>,
            <span class="k">"name"</span>: <span class="s">"Unpublish selected"</span>,
            <span class="k">"description"</span>: <span class="s">"Takes the chosen products off sale."</span>,
            <span class="k">"table"</span>: <span class="s">"product"</span>,
            <span class="k">"restricted"</span>: <span class="n">false</span>
        }
    ],
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Browse the upload folder

GET /media/browse read since 6.6.0

Folders and images inside the shop's upload folder, so an existing image can be picked instead of uploaded again.

Paths are relative to that folder and never escape it: a path pointing outside is refused rather than resolved.

### Query

ParameterTypeDescription

folderstringWhich folder to list, relative to the upload folder. Omit for its root.

offsetintegerOffset into the images, for a folder with many.

### Response expand all

FieldTypeDescription

folderstringThe folder being listed.

parentstringThe folder above, for walking back up.

has\_parentbooleanFalse at the root, where there is nothing above.

foldersobject\[\]The folders inside it.

imagesobject\[\]The images inside it.namestringThe file name.

pathstringRelative to the upload folder, which is what a product image stores.

urlstringAbsolute, ready to display.

totalintegerHow many images the folder holds in all.

offsetintegerEchoes the offset used.

### Errors

CodeHTTPMeans

not\_found404No such folder, or a path that tried to leave the upload folder.

```
curl "$SHOP/hikashop-api/v1/media/browse" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"folder"</span>: <span class="s">""</span>,
        <span class="k">"parent"</span>: <span class="s">""</span>,
        <span class="k">"has_parent"</span>: <span class="n">false</span>,
        <span class="k">"folders"</span>: [],
        <span class="k">"images"</span>: [
            {
                <span class="k">"name"</span>: <span class="s">"demo-0001.png"</span>,
                <span class="k">"path"</span>: <span class="s">"demo-0001.png"</span>,
                <span class="k">"url"</span>: <span class="s">"http://localhost:<span class="n">8080</span>/joomla6_ext/images/com_hikashop/upload/demo-0001.png"</span>
            },
            {
                <span class="k">"name"</span>: <span class="s">"demo-0002-2.png"</span>,
                <span class="k">"path"</span>: <span class="s">"demo-0002-2.png"</span>,
                <span class="k">"url"</span>: <span class="s">"http://localhost:<span class="n">8080</span>/joomla6_ext/images/com_hikashop/upload/demo-0002-2.png"</span>
            },
            {
                <span class="k">"name"</span>: <span class="s">"demo-0002.png"</span>,
                <span class="k">"path"</span>: <span class="s">"demo-0002.png"</span>,
                <span class="k">"url"</span>: <span class="s">"http://localhost:<span class="n">8080</span>/joomla6_ext/images/com_hikashop/upload/demo-0002.png"</span>
            },
            {
                <span class="k">"name"</span>: <span class="s">"demo-0003.png"</span>,
                <span class="k">"path"</span>: <span class="s">"demo-0003.png"</span>,
                <span class="k">"url"</span>: <span class="s">"http://localhost:<span class="n">8080</span>/joomla6_ext/images/com_hikashop/upload/demo-0003.png"</span>
            },
            "… 583 more, trimmed for the example"
        ],
        <span class="k">"total"</span>: <span class="n">587</span>,
        <span class="k">"offset"</span>: <span class="n">0</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Search countries, states and zones

GET /zones read since 6.6.0

The shop's zones, which are its countries, its states and any grouping the merchant made of them. Meant for filling a picker: search for a name, or resolve ids you already hold.

An address stores a zone by its namekey rather than its id, which is why both come back.

### Query

ParameterTypeDescription

searchstringMatches the name.

idsstringComma separated zone ids, to resolve a known set.

typestringRestrict to `country`, `state` or a zone group.

### Response a list expand all

FieldTypeDescription

idinteger

namekeystringWhat an address stores, such as `FRA` or `US-CA`.

namestringTranslated where the shop has a translation for it.

typestring`country`, `state`, or the kind of grouping it is.

```
curl "$SHOP/hikashop-api/v1/zones?search=fra" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: [
        {
            <span class="k">"id"</span>: <span class="n">73</span>,
            <span class="k">"namekey"</span>: <span class="s">"country_France_73"</span>,
            <span class="k">"name"</span>: <span class="s">"France"</span>,
            <span class="k">"type"</span>: <span class="s">"country"</span>
        },
        {
            <span class="k">"id"</span>: <span class="n">2195</span>,
            <span class="k">"namekey"</span>: <span class="s">"state_Al_Jufrah_2195"</span>,
            <span class="k">"name"</span>: <span class="s">"Al Jufrah"</span>,
            <span class="k">"type"</span>: <span class="s">"state"</span>
        },
        {
            <span class="k">"id"</span>: <span class="n">2196</span>,
            <span class="k">"namekey"</span>: <span class="s">"state_Al_Kufrah_2196"</span>,
            <span class="k">"name"</span>: <span class="s">"Al Kufrah"</span>,
            <span class="k">"type"</span>: <span class="s">"state"</span>
        },
        {
            <span class="k">"id"</span>: <span class="n">1631</span>,
            <span class="k">"namekey"</span>: <span class="s">"state_Francisco_Moraz__n_1631"</span>,
            <span class="k">"name"</span>: <span class="s">"Francisco Morazán"</span>,
            <span class="k">"type"</span>: <span class="s">"state"</span>
        },
        "… 4 more, trimmed for the example"
    ],
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Search customers for a picker

GET /users read since 6.6.0

A short list of customers matching a search, for the pickers that restrict a price or a discount to named people. `GET /customers` is the listing to use for anything else.

### Query

ParameterTypeDescription

searchstringMatches the name and the email address.

idsstringComma separated ids, to resolve a known set.

### Response a list expand all

FieldTypeDescription

idintegerThe customer id, which is what a restriction stores.

namestring

emailstringEnough to tell two people of the same name apart.

```
curl "$SHOP/hikashop-api/v1/users?search=a" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: [
        {
            <span class="k">"id"</span>: <span class="n">5424</span>,
            <span class="k">"name"</span>: <span class="s">""</span>,
            <span class="k">"email"</span>: <span class="s">"<joomla-hidden-mail base="" first="YnV5ZXI=" is-email="1" is-link="1" last="ZXhhbXBsZS50ZXN0" text="YnV5ZXJAZXhhbXBsZS50ZXN0">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>"</span>
        },
        {
            <span class="k">"id"</span>: <span class="n">20</span>,
            <span class="k">"name"</span>: <span class="s">""</span>,
            <span class="k">"email"</span>: <span class="s">"<joomla-hidden-mail base="" first="YnV5ZXI=" is-email="1" is-link="1" last="ZXhhbXBsZS50ZXN0" text="YnV5ZXJAZXhhbXBsZS50ZXN0">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>"</span>
        },
        {
            <span class="k">"id"</span>: <span class="n">4939</span>,
            <span class="k">"name"</span>: <span class="s">""</span>,
            <span class="k">"email"</span>: <span class="s">"<joomla-hidden-mail base="" first="YnV5ZXI=" is-email="1" is-link="1" last="ZXhhbXBsZS50ZXN0" text="YnV5ZXJAZXhhbXBsZS50ZXN0">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>"</span>
        },
        {
            <span class="k">"id"</span>: <span class="n">4940</span>,
            <span class="k">"name"</span>: <span class="s">""</span>,
            <span class="k">"email"</span>: <span class="s">"<joomla-hidden-mail base="" first="YnV5ZXI=" is-email="1" is-link="1" last="ZXhhbXBsZS50ZXN0" text="YnV5ZXJAZXhhbXBsZS50ZXN0">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>"</span>
        },
        "… 26 more, trimmed for the example"
    ],
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Reference data for the product editor

GET /products/meta read since 6.6.0

Everything a product form needs to offer choices: the currencies with their formatting, the tax categories, the characteristics and their values, the units, the field definitions, the warehouses and the tags.

One call rather than eight, and it changes rarely, so cache it.

### Response expand all

FieldTypeDescription

currenciesobject\[\]Every published currency, with enough to format an amount the way the shop does.idintegerWhat a price stores.

codestringThe ISO code, such as `EUR`.

symbolstring

namestring

decimalsintegerHow many decimal places to show.

decimal\_sepstringThe decimal separator.

thousands\_sepstringThe thousands separator.

symbol\_beforebooleanWhether the symbol goes before the figure.

spacebooleanWhether a space separates the symbol from the figure.

rounding\_incrementnumberWhat amounts are rounded to, for a currency without small coins.

main\_currency\_idintegerThe shop's own currency.

tax\_categoriesobject\[\]The tax categories a product can be put in.idintegerWhat `tax_id` on a product stores.

namestring

parent\_idintegerThey live in the category tree, so they have a parent like anything else there.

characteristicsobject\[\]Every characteristic in the shop, with its values, for building variants.idinteger

namestring

valuesobject\[\]Its values.idintegerWhat a variant refers to.

valuestringIts name, such as `M`.

weight\_unitsstring\[\]The weight units the shop accepts, such as `kg`.

dimension\_unitsstring\[\]The dimension units the shop accepts, such as `m`.

product\_fieldsobject\[\]The definitions of your own product fields.namekeystringThe key its value is stored under.

typestringWhat to render: `text`, `radio`, `singledropdown`, `file`, and the rest.

raw\_typestringHikaShop's own name for the type.

labelstringTranslated into the operator's language.

defaultstringThe value used when none is given.

requiredbooleanWhether the shop refuses to save without it.

optionsobject\[\]The choices, for a field that has them.valuestringWhat to send back when this choice is picked.

labelstringWhat to show.

label\_keystringThe translation key behind the label, when there is one.

multiplebooleanWhether more than one may be chosen.

translatablebooleanWhether its value can be translated.

upload\_dirstringFor a file field, where its uploads are kept.

allowed\_extensionsstringFor a file field, the extensions it accepts. Empty means the shop default.

date\_formatstringFor a date field, the format it is stored in.

category\_fieldsobject\[\]The definitions of your own category fields.namekeystringThe key its value is stored under.

labelstringTranslated into the operator's language.

typestringWhat to render: `text`, `radio`, `singledropdown`, `file`, and the rest.

raw\_typestringHikaShop's own name for the type.

requiredbooleanWhether the shop refuses to save without it.

defaultstringThe value used when none is given.

optionsobject\[\]The choices, for a field that has them.valuestringWhat to send back when this choice is picked.

labelstringWhat to show.

label\_keystringThe translation key behind the label, when there is one.

multiplebooleanWhether more than one may be chosen.

translatablebooleanWhether its value can be translated.

upload\_dirstringFor a file field, where its uploads are kept.

allowed\_extensionsstringFor a file field, the extensions it accepts. Empty means the shop default.

date\_formatstringFor a date field, the format it is stored in.

bundle\_supportedbooleanWhether this edition can sell bundles.

warehousesobject\[\]The warehouses stock can be held in. Empty when the shop has none.idintegerWhat `warehouse_id` on a product stores.

namestring

tagsobject\[\]The CMS tags a product can carry.idinteger

namestring

parent\_idintegerTags are a tree in both Joomla and WordPress.

```
curl "$SHOP/hikashop-api/v1/products/meta" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"currencies"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">1</span>,
                <span class="k">"code"</span>: <span class="s">"EUR"</span>,
                <span class="k">"symbol"</span>: <span class="s">"€"</span>,
                <span class="k">"name"</span>: <span class="s">"Euro"</span>,
                <span class="k">"decimals"</span>: <span class="n">2</span>,
                <span class="k">"decimal_sep"</span>: <span class="s">","</span>,
                <span class="k">"thousands_sep"</span>: <span class="s">"."</span>,
                <span class="k">"symbol_before"</span>: <span class="n">false</span>,
                <span class="k">"space"</span>: <span class="n">true</span>,
                <span class="k">"rounding_increment"</span>: <span class="n">0</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">2</span>,
                <span class="k">"code"</span>: <span class="s">"USD"</span>,
                <span class="k">"symbol"</span>: <span class="s">"$"</span>,
                <span class="k">"name"</span>: <span class="s">"United States dollar"</span>,
                <span class="k">"decimals"</span>: <span class="n">2</span>,
                <span class="k">"decimal_sep"</span>: <span class="s">"."</span>,
                <span class="k">"thousands_sep"</span>: <span class="s">","</span>,
                <span class="k">"symbol_before"</span>: <span class="n">true</span>,
                <span class="k">"space"</span>: <span class="n">false</span>,
                <span class="k">"rounding_increment"</span>: <span class="n">0</span>
            }
        ],
        <span class="k">"main_currency_id"</span>: <span class="n">1</span>,
        <span class="k">"tax_categories"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">11</span>,
                <span class="k">"name"</span>: <span class="s">"Default tax category"</span>,
                <span class="k">"parent_id"</span>: <span class="n">3</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">3</span>,
                <span class="k">"name"</span>: <span class="s">"taxation category"</span>,
                <span class="k">"parent_id"</span>: <span class="n">1</span>
            }
        ],
        <span class="k">"characteristics"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">1</span>,
                <span class="k">"name"</span>: <span class="s">"Vendor"</span>,
                <span class="k">"values"</span>: []
            },
            {
                <span class="k">"id"</span>: <span class="n">5</span>,
                <span class="k">"name"</span>: <span class="s">"Color"</span>,
                <span class="k">"values"</span>: [
                    {
                        <span class="k">"id"</span>: <span class="n">6</span>,
                        <span class="k">"value"</span>: <span class="s">"Red"</span>
                    },
                    {
                        <span class="k">"id"</span>: <span class="n">7</span>,
                        <span class="k">"value"</span>: <span class="s">"Blue"</span>
                    }
                ]
            },
            {
                <span class="k">"id"</span>: <span class="n">8</span>,
                <span class="k">"name"</span>: <span class="s">"Size"</span>,
                <span class="k">"values"</span>: [
                    {
                        <span class="k">"id"</span>: <span class="n">9</span>,
                        <span class="k">"value"</span>: <span class="s">"S"</span>
                    },
                    {
                        <span class="k">"id"</span>: <span class="n">10</span>,
                        <span class="k">"value"</span>: <span class="s">"L"</span>
                    },
                    {
                        <span class="k">"id"</span>: <span class="n">21</span>,
                        <span class="k">"value"</span>: <span class="s">"M"</span>
                    },
                    {
                        <span class="k">"id"</span>: <span class="n">35</span>,
                        <span class="k">"value"</span>: <span class="s">"XS"</span>
                    },
                    "… 1 more, trimmed for the example"
                ]
            },
            {
                <span class="k">"id"</span>: <span class="n">14</span>,
                <span class="k">"name"</span>: <span class="s">"Colour"</span>,
                <span class="k">"values"</span>: [
                    {
                        <span class="k">"id"</span>: <span class="n">15</span>,
                        <span class="k">"value"</span>: <span class="s">"Charcoal"</span>
                    },
                    {
                        <span class="k">"id"</span>: <span class="n">16</span>,
                        <span class="k">"value"</span>: <span class="s">"Navy"</span>
                    },
                    {
                        <span class="k">"id"</span>: <span class="n">17</span>,
                        <span class="k">"value"</span>: <span class="s">"Oatmeal"</span>
                    },
                    {
                        <span class="k">"id"</span>: <span class="n">18</span>,
                        <span class="k">"value"</span>: <span class="s">"Forest"</span>
                    },
                    "… 2 more, trimmed for the example"
                ]
            },
            "… 1 more, trimmed for the example"
        ],
        <span class="k">"weight_units"</span>: [
            "kg",
            "g",
            "mg",
            "lb",
            "… 2 more, trimmed for the example"
        ],
        <span class="k">"dimension_units"</span>: [
            "m",
            "dm",
            "cm",
            "mm",
            "… 3 more, trimmed for the example"
        ],
        <span class="k">"product_fields"</span>: [
            {
                <span class="k">"namekey"</span>: <span class="s">"test_ajax_image"</span>,
                <span class="k">"type"</span>: <span class="s">"ajaximage"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"ajaximage"</span>,
                <span class="k">"label"</span>: <span class="s">"Test Ajax Image"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">false</span>,
                <span class="k">"options"</span>: [],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">"%Y-%m-%d"</span>
            },
            {
                <span class="k">"namekey"</span>: <span class="s">"product_gtin"</span>,
                <span class="k">"type"</span>: <span class="s">"text"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"text"</span>,
                <span class="k">"label"</span>: <span class="s">"GTIN"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">false</span>,
                <span class="k">"options"</span>: [],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            }
        ],
        <span class="k">"category_fields"</span>: [],
        <span class="k">"bundle_supported"</span>: <span class="n">true</span>,
        <span class="k">"warehouses"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">1</span>,
                <span class="k">"name"</span>: <span class="s">"Default Warehouse"</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">2</span>,
                <span class="k">"name"</span>: <span class="s">"Main Warehouse (renamed)"</span>
            }
        ],
        <span class="k">"tags"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Replace a product's prices

PUT /products/**{id}**/prices write since 6.6.0

Replaces the whole price set, it does not merge into it. Send every price the product should have, including the ones you are not changing; anything you leave out is deleted.

That is deliberate, because a price set is a set: quantity breaks and audience restrictions only make sense against each other.

### Path

ParameterTypeDescription

idrequiredintegerThe product or variant.

### Body

FieldTypeDescription

pricesrequiredobject\[\]The complete set. Each needs at least a `value` and a `currency_id`; `min_quantity`, `access`, `users`, `zone_ids`, `start_date` and `end_date` are optional and default to no restriction.

### Response a list expand all

FieldTypeDescription

idinteger

valuenumberTax excluded, as stored.

currency\_idinteger

min\_quantityintegerFrom how many items this row applies, which is how a quantity break is expressed.

accessobjectWhich user groups the price is for.modestring`all`, `none` or `groups`.

groupsinteger\[\]User group ids, not view levels.

usersinteger\[\]Named customers, empty for everyone.

zone\_idsinteger\[\]Zones it applies in, empty for everywhere.

start\_dateinteger\|nullUnix timestamp.

end\_dateinteger\|nullUnix timestamp.

### Errors

CodeHTTPMeans

invalid\_request400No prices array was sent.

invalid\_price400A price in the set cannot be stored, and the message says which one and why. Nothing is saved: a set is replaced whole or not at all.

not\_found404No such product, or the operator may not change it.

```
curl -X PUT "$SHOP/hikashop-api/v1/products/{id}/prices" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "prices": [
        {
            "value": 19.9,
            "currency_id": 1,
            "min_quantity": 1
        }
    ]
}'
```

```
{
    <span class="k">"data"</span>: [
        {
            <span class="k">"id"</span>: <span class="n">4947</span>,
            <span class="k">"value"</span>: <span class="n">19.9</span>,
            <span class="k">"currency_id"</span>: <span class="n">1</span>,
            <span class="k">"min_quantity"</span>: <span class="n">1</span>,
            <span class="k">"access"</span>: {
                <span class="k">"mode"</span>: <span class="s">"all"</span>,
                <span class="k">"groups"</span>: []
            },
            <span class="k">"users"</span>: [],
            <span class="k">"zone_ids"</span>: [],
            <span class="k">"start_date"</span>: <span class="n">0</span>,
            <span class="k">"end_date"</span>: <span class="n">0</span>
        }
    ],
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Replace a product's categories

PUT /products/**{id}**/categories write since 6.6.0

Replaces the set of categories the product is in. As with the prices, send the complete set: what you leave out is removed.

### Path

ParameterTypeDescription

idrequiredintegerThe product.

### Body

FieldTypeDescription

categoriesrequiredinteger\[\]The complete set of category ids. An empty array takes the product out of every category, which hides it from the shop.

### Response a list expand all

FieldTypeDescription

idintegerThe category.

namestringIts name, so a client need not look it up.

### Errors

CodeHTTPMeans

not\_found404No such product, or the operator may not change it.

```
curl -X PUT "$SHOP/hikashop-api/v1/products/{id}/categories" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "categories": [
        "2"
    ]
}'
```

```
{
    <span class="k">"data"</span>: [
        {
            <span class="k">"id"</span>: <span class="n">2</span>,
            <span class="k">"name"</span>: <span class="s">"product category"</span>
        }
    ],
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## A product's translations

GET /products/**{id}**/translations read since 6.6.0

Which of a record's texts can be translated, what they say now in each language, and what the original says. `enabled` is false on a single-language shop, where there is nothing to do.

`columns` is the list of translatable things: HikaShop's own (the name, the description, the SEO texts) plus every custom field the merchant flagged translatable. It is built the same way the backend builds it, so what you are offered is exactly what the shop will store.

The labels and values of a custom field itself are website configuration and are not offered here; they belong in the backend.

### Path

ParameterTypeDescription

idrequiredintegerThe product.

### Response expand all

FieldTypeDescription

enabledbooleanFalse on a single-language shop, where the rest is empty.

languagesobject\[\]The shop's languages. The default one is marked and comes last, because its text is the original rather than a translation of it.idinteger

codestringThe tag, such as `fr-FR`.

shortcodestringThe lower-case underscored form the translation tables key on.

site\_defaultbooleanTrue for the language the shop is written in.

columnsobject\[\]What can be translated on this record: HikaShop's own texts plus every custom field flagged translatable.namestringThe column name, such as `product_name`. This is the key to send a translation under.

typestring`text` for a line, `textarea` for prose, so a client knows which control to draw.

valuesobjectWhat each language says now, keyed by language code and then by column. Keyed by language code, and within that by column name, both of which depend on the shop.

originalobjectWhat the record itself says, keyed by column, so a translator can see what they are translating. Keyed by column name, which depends on the fields this shop has.

### Errors

CodeHTTPMeans

not\_found404No such record, or the operator may not see it.

translation\_disabled400This shop does not translate content.

```
curl "$SHOP/hikashop-api/v1/products/1/translations" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"enabled"</span>: <span class="n">true</span>,
        <span class="k">"languages"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">2</span>,
                <span class="k">"code"</span>: <span class="s">"fr-FR"</span>,
                <span class="k">"shortcode"</span>: <span class="s">"fr_fr"</span>,
                <span class="k">"site_default"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">1</span>,
                <span class="k">"code"</span>: <span class="s">"en-GB"</span>,
                <span class="k">"shortcode"</span>: <span class="s">"en_gb"</span>,
                <span class="k">"site_default"</span>: <span class="n">true</span>
            }
        ],
        <span class="k">"columns"</span>: [
            {
                <span class="k">"name"</span>: <span class="s">"product_name"</span>,
                <span class="k">"type"</span>: <span class="s">"text"</span>
            },
            {
                <span class="k">"name"</span>: <span class="s">"product_description"</span>,
                <span class="k">"type"</span>: <span class="s">"html"</span>
            },
            {
                <span class="k">"name"</span>: <span class="s">"product_page_title"</span>,
                <span class="k">"type"</span>: <span class="s">"text"</span>
            },
            {
                <span class="k">"name"</span>: <span class="s">"product_url"</span>,
                <span class="k">"type"</span>: <span class="s">"text"</span>
            },
            "… 4 more, trimmed for the example"
        ],
        <span class="k">"original"</span>: {
            <span class="k">"product_name"</span>: <span class="s">"Test Product (Vendor 2)"</span>,
            <span class="k">"product_description"</span>: <span class="s">"Test product owned by vendor 2"</span>,
            <span class="k">"product_page_title"</span>: <span class="s">""</span>,
            <span class="k">"product_url"</span>: <span class="s">""</span>,
            <span class="k">"product_meta_description"</span>: <span class="s">""</span>,
            <span class="k">"product_keywords"</span>: <span class="s">""</span>,
            <span class="k">"product_alias"</span>: <span class="s">""</span>,
            <span class="k">"product_canonical"</span>: <span class="s">""</span>
        },
        <span class="k">"values"</span>: {
            <span class="k">"2"</span>: {
                <span class="k">"product_name"</span>: <span class="s">"Lampe de bureau"</span>
            }
        }
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## A category's translations

GET /categories/**{id}**/translations read since 6.6.0

The same as for a product, for a category: its name, its description, its SEO texts and its translatable custom fields.

### Path

ParameterTypeDescription

idrequiredintegerThe category.

### Response expand all

FieldTypeDescription

enabledbooleanFalse on a single-language shop, where the rest is empty.

languagesobject\[\]The shop's languages. The default one is marked and comes last, because its text is the original rather than a translation of it.idinteger

codestringThe tag, such as `fr-FR`.

shortcodestringThe lower-case underscored form the translation tables key on.

site\_defaultbooleanTrue for the language the shop is written in.

columnsobject\[\]What can be translated on this record: HikaShop's own texts plus every custom field flagged translatable.namestringThe column name, such as `product_name`. This is the key to send a translation under.

typestring`text` for a line, `textarea` for prose, so a client knows which control to draw.

valuesobjectWhat each language says now, keyed by language code and then by column. Keyed by language code, and within that by column name, both of which depend on the shop.

originalobjectWhat the record itself says, keyed by column, so a translator can see what they are translating. Keyed by column name, which depends on the fields this shop has.

### Errors

CodeHTTPMeans

not\_found404No such record, or the operator may not see it.

translation\_disabled400This shop does not translate content.

```
curl "$SHOP/hikashop-api/v1/categories/2/translations" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"enabled"</span>: <span class="n">true</span>,
        <span class="k">"languages"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">2</span>,
                <span class="k">"code"</span>: <span class="s">"fr-FR"</span>,
                <span class="k">"shortcode"</span>: <span class="s">"fr_fr"</span>,
                <span class="k">"site_default"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">1</span>,
                <span class="k">"code"</span>: <span class="s">"en-GB"</span>,
                <span class="k">"shortcode"</span>: <span class="s">"en_gb"</span>,
                <span class="k">"site_default"</span>: <span class="n">true</span>
            }
        ],
        <span class="k">"columns"</span>: [
            {
                <span class="k">"name"</span>: <span class="s">"category_name"</span>,
                <span class="k">"type"</span>: <span class="s">"text"</span>
            },
            {
                <span class="k">"name"</span>: <span class="s">"category_description"</span>,
                <span class="k">"type"</span>: <span class="s">"html"</span>
            },
            {
                <span class="k">"name"</span>: <span class="s">"category_product_page_info"</span>,
                <span class="k">"type"</span>: <span class="s">"html"</span>
            },
            {
                <span class="k">"name"</span>: <span class="s">"category_page_title"</span>,
                <span class="k">"type"</span>: <span class="s">"text"</span>
            },
            "… 4 more, trimmed for the example"
        ],
        <span class="k">"original"</span>: {
            <span class="k">"category_name"</span>: <span class="s">"product category"</span>,
            <span class="k">"category_description"</span>: <span class="s">""</span>,
            <span class="k">"category_product_page_info"</span>: <span class="s">""</span>,
            <span class="k">"category_page_title"</span>: <span class="s">""</span>,
            <span class="k">"category_meta_description"</span>: <span class="s">""</span>,
            <span class="k">"category_keywords"</span>: <span class="s">""</span>,
            <span class="k">"category_alias"</span>: <span class="s">""</span>,
            <span class="k">"category_canonical"</span>: <span class="s">""</span>
        },
        <span class="k">"values"</span>: {
            <span class="k">"2"</span>: {
                <span class="k">"category_name"</span>: <span class="s">"Sacs et vêtements"</span>
            }
        }
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Save a product's translations

PUT /products/**{id}**/translations write since 6.6.0

Writes the translations of one record. Send only the languages you changed; the rest are left alone.

Where the shop uses Falang, the values go into its tables. Where it does not, they become language overrides keyed on the original text, which is why renaming a product re-keys its translations rather than losing them.

### Path

ParameterTypeDescription

idrequiredintegerThe product.

### Body

An object keyed by language, each holding an object of column name to text:

`{ "2": { "product_name": "Lampe de bureau", "product_description": "…" } }`

The keys are the language ids from `languages` in the GET, and the column names are the ones from `columns`. A language you do not send is left alone, and so is a column you do not send within a language you do.

### Response expand all

FieldTypeDescription

idintegerThe record that was saved.

savedintegerHow many languages were written, so a client can tell that something was actually stored.

### Errors

CodeHTTPMeans

not\_found404No such record, or the operator may not change it.

translation\_disabled400This shop does not translate content.

```
curl -X PUT "$SHOP/hikashop-api/v1/products/1/translations" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "2": {
        "product_name": "Lampe de bureau"
    }
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">1</span>,
        <span class="k">"saved"</span>: <span class="n">1</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Save a category's translations

PUT /categories/**{id}**/translations write since 6.6.0

The same as for a product, for a category.

### Path

ParameterTypeDescription

idrequiredintegerThe category.

### Body

An object keyed by language, each holding an object of column name to text:

`{ "2": { "product_name": "Lampe de bureau", "product_description": "…" } }`

The keys are the language ids from `languages` in the GET, and the column names are the ones from `columns`. A language you do not send is left alone, and so is a column you do not send within a language you do.

### Response expand all

FieldTypeDescription

idintegerThe record that was saved.

savedintegerHow many languages were written.

### Errors

CodeHTTPMeans

not\_found404No such record, or the operator may not change it.

translation\_disabled400This shop does not translate content.

```
curl -X PUT "$SHOP/hikashop-api/v1/categories/2/translations" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "2": {
        "category_name": "Sacs et v\u00eatements"
    }
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">2</span>,
        <span class="k">"saved"</span>: <span class="n">1</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Dashboard figures

GET /stats/dashboard read since 6.6.0

Revenue, orders, average basket and new customers over a period, the same figures again for the period before it so a change can be shown, the series behind them, and the best sellers.

Only orders the shop counts as sold are included, so a cancelled order does not inflate a total. Amounts are in the shop's own currency.

### Query

ParameterTypeDescription

rangestring`day`, `week`, `month` or `year`. Defaults to `month`.

### Response expand all

FieldTypeDescription

rangestringThe period the figures cover.

currency\_idintegerThe shop's currency, which every amount here is in.

totalsobjectThe four headline figures.revenuenumberTaken in the period.

ordersintegerHow many were placed.

average\_ordernumberRevenue divided by orders.

customersintegerNew customers in the period.

previousobjectThe same four figures for the preceding period of the same length, for a comparison.revenuenumberTaken in the preceding period.

ordersintegerPlaced in it.

average\_ordernumberIts average basket.

customersintegerNew customers in it.

series\_granularitystringWhether the series is by day, week, month or year, which follows from the range.

revenue\_seriesobject\[\]One point per interval, for a chart.datestringThe interval, as a date.

revenuenumberTaken in it.

top\_productsobject\[\]The best sellers of the period.namestring

quantityintegerHow many were sold.

```
curl "$SHOP/hikashop-api/v1/stats/dashboard?range=month" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"range"</span>: <span class="s">"month"</span>,
        <span class="k">"currency_id"</span>: <span class="n">1</span>,
        <span class="k">"totals"</span>: {
            <span class="k">"revenue"</span>: <span class="n">0</span>,
            <span class="k">"orders"</span>: <span class="n">0</span>,
            <span class="k">"average_order"</span>: <span class="n">0</span>,
            <span class="k">"customers"</span>: <span class="n">0</span>
        },
        <span class="k">"previous"</span>: {
            <span class="k">"revenue"</span>: <span class="n">6309.8</span>,
            <span class="k">"orders"</span>: <span class="n">22</span>,
            <span class="k">"average_order"</span>: <span class="n">286.81</span>,
            <span class="k">"customers"</span>: <span class="n">18</span>
        },
        <span class="k">"series_granularity"</span>: <span class="s">"day"</span>,
        <span class="k">"revenue_series"</span>: [
            {
                <span class="k">"date"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"revenue"</span>: <span class="n">0</span>
            },
            {
                <span class="k">"date"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"revenue"</span>: <span class="n">0</span>
            },
            {
                <span class="k">"date"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"revenue"</span>: <span class="n">0</span>
            },
            {
                <span class="k">"date"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"revenue"</span>: <span class="n">0</span>
            },
            "… 27 more, trimmed for the example"
        ],
        <span class="k">"top_products"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## The user groups

GET /groups read since 6.6.0

The CMS user groups, for the pickers that restrict a price, a discount or a product to some of them. The list is the same shape on Joomla and on WordPress, which is the point of it: a client does not need to know which it is talking to.

These are the ids an `access` object holds. They are user groups and not Joomla view levels.

### Response a list expand all

FieldTypeDescription

idintegerWhat an access object stores.

titlestringThe name of the group.

```
curl "$SHOP/hikashop-api/v1/groups" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: [
        {
            <span class="k">"id"</span>: <span class="n">1</span>,
            <span class="k">"title"</span>: <span class="s">"Mr"</span>
        },
        {
            <span class="k">"id"</span>: <span class="n">9</span>,
            <span class="k">"title"</span>: <span class="s">"Mr"</span>
        },
        {
            <span class="k">"id"</span>: <span class="n">6</span>,
            <span class="k">"title"</span>: <span class="s">"Mr"</span>
        },
        {
            <span class="k">"id"</span>: <span class="n">7</span>,
            <span class="k">"title"</span>: <span class="s">"Mr"</span>
        },
        "… 5 more, trimmed for the example"
    ],
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Price a product in an order

GET /orders/**{id}**/products/precompute read since 6.6.0

What a product would cost on this order, before adding it. The order's customer, currency and zone all bear on the price, so this asks the shop rather than guessing from the catalogue.

Use it to show a line before it is committed, then `POST /orders/{id}/products` to add it.

### Path

ParameterTypeDescription

idrequiredintegerThe order.

### Query

ParameterTypeDescription

product\_idrequiredintegerThe product or variant to price.

quantityintegerHow many, which matters where the product has quantity breaks. Defaults to `1`.

### Response expand all

FieldTypeDescription

product\_idintegerWhat was priced.

namestring

codestringIts SKU.

quantityintegerThe quantity the price was worked out for.

pricenumberUnit price, tax excluded, in the order currency.

taxnumberTax per unit, worked out for this order rather than in general.

tax\_namekeysstring\[\]Which tax rates that came from.

### Errors

CodeHTTPMeans

not\_found404No such order or no such product, or the operator may not see them.

```
curl "$SHOP/hikashop-api/v1/orders/{id}/products/precompute?product_id=1&quantity=2" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"product_id"</span>: <span class="n">1</span>,
        <span class="k">"name"</span>: <span class="s">"Test Product (Vendor 2)"</span>,
        <span class="k">"code"</span>: <span class="s">"TEST001"</span>,
        <span class="k">"quantity"</span>: <span class="n">2</span>,
        <span class="k">"price"</span>: <span class="n">9.99</span>,
        <span class="k">"tax"</span>: <span class="n">0</span>,
        <span class="k">"tax_namekeys"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Read one customer

GET /customers/**{id}** read since 6.6.0

A customer with their addresses, their orders, which groups they are in and your own customer fields.

`can_edit_account` and `groups_editable` are worth reading before drawing a form: they say whether this operator may change this particular account at all, so a client can leave the controls out rather than offer something that will be refused. A customer can have many addresses and one default of each kind.

### Path

ParameterTypeDescription

idrequiredintegerThe customer id.

### Response expand all

FieldTypeDescription

idintegerThe HikaShop customer id, which is what every customer route takes.

cms\_idintegerThe Joomla or WordPress user id, `0` for a guest with no account.

namestring

emailstring

usernamestringThe login, empty for a guest.

typestring`registered` or `guest`.

blockedbooleanWhether the CMS account is disabled.

can\_edit\_accountbooleanWhether this operator may change the login and password of this particular account. False for an account above their own level, which is how a super user is protected from staff.

groups\_editablebooleanWhether this operator may change which groups the customer is in.

groupsobject\[\]The groups they are in.idinteger

titlestring

available\_groupsobject\[\]Every group, with whether this operator may put the customer into it, so a picker can grey out the rest rather than offering a refusal.idinteger

titlestring

assignablebooleanFalse for a group this operator may not grant.

createdintegerUnix timestamp of the first time the shop saw them.

addressesobject\[\]Their addresses, defaults first.idinteger

typesstring\[\]Which of `billing` and `shipping` it is used for.

namestring

companystring

streetstring

citystring

post\_codestring

telephonestring

defaultbooleanWhether it is the default for one of its types.

formattedobjectThe address laid out the way this shop lays addresses out, which depends on its address format setting.textstringSeveral lines, for an invoice or a label.

one\_linestringOne line, for a list.

ordersobject\[\]Their orders, newest first, enough to list them.idinteger

numberstringThe number the customer sees.

statusstringA namekey.

createdintegerUnix timestamp.

totalnumberTax included, in the order currency.

currency\_idintegerThat currency.

fieldsobject\[\]The definitions of your own customer fields.

custom\_fieldsobjectTheir values, keyed by namekey. The keys depend on the shop; `fields` says what they are.

custom\_field\_filesobjectFor a field holding a file, the file behind the value. Keyed the same way.

sectionsobject\[\]Information other plugins show on this record, each with a `key`, a `title` and `rows` (`label`, `value`, and optionally `url`, `badge` and `ref`). Empty when no plugin adds any; on a customer, core adds their paid downloads. See the guide on adding information and settings.

extensionsobject\[\]Settings other plugins keep on this record, in groups (`key`, `title`, `fields`), each field described like a custom field plus its current `value`. Send changes back as `extensions` with the record's save. Empty when no plugin adds any.

### Errors

CodeHTTPMeans

not\_found404No such customer, or the operator may not see them.

```
curl "$SHOP/hikashop-api/v1/customers/{id}" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">14</span>,
        <span class="k">"cms_id"</span>: <span class="n">156</span>,
        <span class="k">"name"</span>: <span class="s">"Admin"</span>,
        <span class="k">"email"</span>: <span class="s">"<joomla-hidden-mail base="" first="YnV5ZXI=" is-email="1" is-link="1" last="ZXhhbXBsZS50ZXN0" text="YnV5ZXJAZXhhbXBsZS50ZXN0">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>"</span>,
        <span class="k">"username"</span>: <span class="s">"admin"</span>,
        <span class="k">"type"</span>: <span class="s">"registered"</span>,
        <span class="k">"blocked"</span>: <span class="n">false</span>,
        <span class="k">"can_edit_account"</span>: <span class="n">false</span>,
        <span class="k">"groups_editable"</span>: <span class="n">false</span>,
        <span class="k">"groups"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">8</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>
            }
        ],
        <span class="k">"available_groups"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">1</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">9</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">6</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">7</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            "… 5 more, trimmed for the example"
        ],
        <span class="k">"created"</span>: <span class="n">1778653121</span>,
        <span class="k">"addresses"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">4372</span>,
                <span class="k">"types"</span>: [
                    "shipping"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">true</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            {
                <span class="k">"id"</span>: <span class="n">4371</span>,
                <span class="k">"types"</span>: [
                    "billing"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">true</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            {
                <span class="k">"id"</span>: <span class="n">4380</span>,
                <span class="k">"types"</span>: [
                    "billing"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">false</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            {
                <span class="k">"id"</span>: <span class="n">4379</span>,
                <span class="k">"types"</span>: [
                    "billing"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">false</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            "… 4 more, trimmed for the example"
        ],
        <span class="k">"orders"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">2</span>,
                <span class="k">"number"</span>: <span class="s">"TEST-VOTE-1"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1786877040</span>,
                <span class="k">"total"</span>: <span class="n">100</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">18</span>,
                <span class="k">"number"</span>: <span class="s">"U18"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1786358640</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">20</span>,
                <span class="k">"number"</span>: <span class="s">"X20"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1785840240</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">16</span>,
                <span class="k">"number"</span>: <span class="s">"S16"</span>,
                <span class="k">"status"</span>: <span class="s">"created"</span>,
                <span class="k">"created"</span>: <span class="n">1783345950</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            "… 96 more, trimmed for the example"
        ],
        <span class="k">"fields"</span>: [],
        <span class="k">"custom_fields"</span>: [],
        <span class="k">"custom_field_files"</span>: [],
        <span class="k">"sections"</span>: [],
        <span class="k">"extensions"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Delete a customer

DELETE /customers/**{id}** write since 6.6.0

Removes a customer and their addresses.

A customer with orders is refused, which is what the backend does too: delete their orders first, and then the customer.

### Path

ParameterTypeDescription

idrequiredintegerThe customer id.

### Response expand all

FieldTypeDescription

deletedbooleanTrue when the row is gone.

### Errors

CodeHTTPMeans

not\_found404No such customer, or the operator may not delete them.

has\_orders400They have orders. Delete those first.

delete\_failed400The shop refused to delete the row.

```
curl -X DELETE "$SHOP/hikashop-api/v1/customers/{id}" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"deleted"</span>: <span class="n">5424</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Update a customer's profile

PUT /customers/**{id}** write since 6.6.0

Changes the name, the email address, the login, the password, the user groups and your own customer fields, and answers with the customer as it now stands.

The password is written straight into the CMS account and is never returned by anything. Changing the email of a registered customer changes the account they log in with, which is why a clash is refused rather than silently ignored.

### Path

ParameterTypeDescription

idrequiredintegerThe customer id.

### Body

FieldTypeDescription

namestringTheir display name.

emailstringMust not belong to another account.

usernamestringThe login, for a registered customer.

passwordstringA new password. Send it only when changing it.

groupsinteger\[\]The user groups they belong to, as ids from `GET /groups`.

custom\_fieldsobjectYour own customer fields, keyed by namekey.

extensionsobjectSettings other plugins keep on this record, as `{ group key: { namekey: value } }`, for the groups and fields its `extensions` lists. Saved after the record's own fields. See the guide on adding information and settings.

### Response expand all

FieldTypeDescription

idintegerThe HikaShop customer id, which is what every customer route takes.

cms\_idintegerThe Joomla or WordPress user id, `0` for a guest with no account.

namestring

emailstring

usernamestringThe login, empty for a guest.

typestring`registered` or `guest`.

blockedbooleanWhether the CMS account is disabled.

can\_edit\_accountbooleanWhether this operator may change the login and password of this particular account. False for an account above their own level, which is how a super user is protected from staff.

groups\_editablebooleanWhether this operator may change which groups the customer is in.

groupsobject\[\]The groups they are in.idinteger

titlestring

available\_groupsobject\[\]Every group, with whether this operator may put the customer into it, so a picker can grey out the rest rather than offering a refusal.idinteger

titlestring

assignablebooleanFalse for a group this operator may not grant.

createdintegerUnix timestamp of the first time the shop saw them.

addressesobject\[\]Their addresses, defaults first.idinteger

typesstring\[\]Which of `billing` and `shipping` it is used for.

namestring

companystring

streetstring

citystring

post\_codestring

telephonestring

defaultbooleanWhether it is the default for one of its types.

formattedobjectThe address laid out the way this shop lays addresses out, which depends on its address format setting.textstringSeveral lines, for an invoice or a label.

one\_linestringOne line, for a list.

ordersobject\[\]Their orders, newest first, enough to list them.idinteger

numberstringThe number the customer sees.

statusstringA namekey.

createdintegerUnix timestamp.

totalnumberTax included, in the order currency.

currency\_idintegerThat currency.

fieldsobject\[\]The definitions of your own customer fields.

custom\_fieldsobjectTheir values, keyed by namekey. The keys depend on the shop; `fields` says what they are.

custom\_field\_filesobjectFor a field holding a file, the file behind the value. Keyed the same way.

sectionsobject\[\]Information other plugins show on this record, each with a `key`, a `title` and `rows` (`label`, `value`, and optionally `url`, `badge` and `ref`). Empty when no plugin adds any; on a customer, core adds their paid downloads. See the guide on adding information and settings.

extensionsobject\[\]Settings other plugins keep on this record, in groups (`key`, `title`, `fields`), each field described like a custom field plus its current `value`. Send changes back as `extensions` with the record's save. Empty when no plugin adds any.

### Errors

CodeHTTPMeans

not\_found404No such customer, or the operator may not change them.

invalid\_email400The email address is not one.

forbidden\_target400The operator may not change this particular account, which is how a super user is protected from being edited by staff.

username\_taken400Another account has that login.

email\_taken400Another account has that email address.

account\_save\_failed400The CMS refused to save the account.

invalid\_fields400One of your own fields was rejected by its own rules.

invalid\_extensions400The record's own fields were saved, but a plugin refused some of its values: &#96;error.details&#96; says which, as &#96;{ group key: { namekey: message } }&#96;.

```
curl -X PUT "$SHOP/hikashop-api/v1/customers/{id}" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Alex Marchand"
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">20</span>,
        <span class="k">"cms_id"</span>: <span class="n">0</span>,
        <span class="k">"name"</span>: <span class="s">"John Doe"</span>,
        <span class="k">"email"</span>: <span class="s">"<joomla-hidden-mail base="" first="YnV5ZXI=" is-email="1" is-link="1" last="ZXhhbXBsZS50ZXN0" text="YnV5ZXJAZXhhbXBsZS50ZXN0">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>"</span>,
        <span class="k">"username"</span>: <span class="s">""</span>,
        <span class="k">"type"</span>: <span class="s">"guest"</span>,
        <span class="k">"blocked"</span>: <span class="n">false</span>,
        <span class="k">"can_edit_account"</span>: <span class="n">true</span>,
        <span class="k">"groups_editable"</span>: <span class="n">false</span>,
        <span class="k">"groups"</span>: [],
        <span class="k">"available_groups"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">1</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">9</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">6</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">7</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            "… 5 more, trimmed for the example"
        ],
        <span class="k">"created"</span>: <span class="n">1786963440</span>,
        <span class="k">"addresses"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">26</span>,
                <span class="k">"types"</span>: [
                    "billing"
                ],
                <span class="k">"name"</span>: <span class="s">"John Doe"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">true</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            {
                <span class="k">"id"</span>: <span class="n">25</span>,
                <span class="k">"types"</span>: [
                    "shipping"
                ],
                <span class="k">"name"</span>: <span class="s">"John Doe"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">true</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            }
        ],
        <span class="k">"orders"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">26</span>,
                <span class="k">"number"</span>: <span class="s">"B2D6"</span>,
                <span class="k">"status"</span>: <span class="s">"created"</span>,
                <span class="k">"created"</span>: <span class="n">1785338765</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">28</span>,
                <span class="k">"number"</span>: <span class="s">"B2F8"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1785321840</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">30</span>,
                <span class="k">"number"</span>: <span class="s">"ZBUNDLE"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1784803440</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">22</span>,
                <span class="k">"number"</span>: <span class="s">"Z22"</span>,
                <span class="k">"status"</span>: <span class="s">"created"</span>,
                <span class="k">"created"</span>: <span class="n">1783721823</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            }
        ],
        <span class="k">"fields"</span>: [],
        <span class="k">"custom_fields"</span>: [],
        <span class="k">"custom_field_files"</span>: [],
        <span class="k">"sections"</span>: [],
        <span class="k">"extensions"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Give a guest an account

POST /customers/**{id}**/account write since 6.6.0

Turns a guest into a registered customer, keeping their orders and addresses, and answers with the customer as it now stands.

This is the useful direction: someone ordered without an account, then asked for one. Creating the account separately would leave their history behind.

### Path

ParameterTypeDescription

idrequiredintegerThe guest customer.

### Body

FieldTypeDescription

usernamerequiredstringThe login to create.

passwordrequiredstringTheir password. Never returned by anything afterwards.

namestringTheir display name, defaulting to the one on the guest record.

groupsinteger\[\]The user groups to put them in.

### Response expand all

FieldTypeDescription

idintegerThe HikaShop customer id, which is what every customer route takes.

cms\_idintegerThe Joomla or WordPress user id, `0` for a guest with no account.

namestring

emailstring

usernamestringThe login, empty for a guest.

typestring`registered` or `guest`.

blockedbooleanWhether the CMS account is disabled.

can\_edit\_accountbooleanWhether this operator may change the login and password of this particular account. False for an account above their own level, which is how a super user is protected from staff.

groups\_editablebooleanWhether this operator may change which groups the customer is in.

groupsobject\[\]The groups they are in.idinteger

titlestring

available\_groupsobject\[\]Every group, with whether this operator may put the customer into it, so a picker can grey out the rest rather than offering a refusal.idinteger

titlestring

assignablebooleanFalse for a group this operator may not grant.

createdintegerUnix timestamp of the first time the shop saw them.

addressesobject\[\]Their addresses, defaults first.idinteger

typesstring\[\]Which of `billing` and `shipping` it is used for.

namestring

companystring

streetstring

citystring

post\_codestring

telephonestring

defaultbooleanWhether it is the default for one of its types.

formattedobjectThe address laid out the way this shop lays addresses out, which depends on its address format setting.textstringSeveral lines, for an invoice or a label.

one\_linestringOne line, for a list.

ordersobject\[\]Their orders, newest first, enough to list them.idinteger

numberstringThe number the customer sees.

statusstringA namekey.

createdintegerUnix timestamp.

totalnumberTax included, in the order currency.

currency\_idintegerThat currency.

fieldsobject\[\]The definitions of your own customer fields.

custom\_fieldsobjectTheir values, keyed by namekey. The keys depend on the shop; `fields` says what they are.

custom\_field\_filesobjectFor a field holding a file, the file behind the value. Keyed the same way.

### Errors

CodeHTTPMeans

not\_found404No such customer.

already\_registered400They already have an account.

missing\_credentials400A username and a password are both required.

invalid\_email400The address on the guest record is not usable as an account email.

email\_taken400Another account has that email address.

username\_taken400Another account has that login.

account\_save\_failed400The CMS refused to create the account.

```
curl -X POST "$SHOP/hikashop-api/v1/customers/{id}/account" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "doccapture5412",
    "password": "not-a-real-password-9x"
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">5412</span>,
        <span class="k">"cms_id"</span>: <span class="n">181</span>,
        <span class="k">"name"</span>: <span class="s">"<joomla-hidden-mail base="" first="YnV5ZXI=" is-email="1" is-link="1" last="ZXhhbXBsZS50ZXN0" text="YnV5ZXJAZXhhbXBsZS50ZXN0">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>"</span>,
        <span class="k">"email"</span>: <span class="s">"<joomla-hidden-mail base="" first="YnV5ZXI=" is-email="1" is-link="1" last="ZXhhbXBsZS50ZXN0" text="YnV5ZXJAZXhhbXBsZS50ZXN0">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>"</span>,
        <span class="k">"username"</span>: <span class="s">"doccapture5412"</span>,
        <span class="k">"type"</span>: <span class="s">"registered"</span>,
        <span class="k">"blocked"</span>: <span class="n">false</span>,
        <span class="k">"can_edit_account"</span>: <span class="n">true</span>,
        <span class="k">"groups_editable"</span>: <span class="n">false</span>,
        <span class="k">"groups"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">2</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>
            }
        ],
        <span class="k">"available_groups"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">1</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">9</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">6</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">7</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            "… 5 more, trimmed for the example"
        ],
        <span class="k">"created"</span>: <span class="n">1789923608</span>,
        <span class="k">"addresses"</span>: [],
        <span class="k">"orders"</span>: [],
        <span class="k">"fields"</span>: [],
        <span class="k">"custom_fields"</span>: [],
        <span class="k">"custom_field_files"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Create a product

POST /products public since 6.6.0

Creates a product and answers with its id. Only the name is required; everything else can be set now or later with `PUT /products/{id}`.

Prices, images and categories are separate calls, so a new product is not sellable until it has at least one price.

### Body

Any of the fields a product carries: `name` (required), `code`, `description`, `published`, `msrp`, `gtin`, `condition`, `weight`, `weight_unit`, `width`, `height`, `length`, `dimension_unit`, `min_per_order`, `max_per_order`, `sale_start`, `sale_end`, `page_title`, `meta_description`, `keywords`, `canonical`, `url`, `alias`, `tax_id`, `manufacturer_id`, `contact`, `warehouse_id`, plus `access` and `custom_fields`.

They mean what they mean on `GET /products/{id}`. A field the shop's own schema does not have is ignored rather than refused, which is what lets one client talk to shops of different vintages.

### Response expand all

FieldTypeDescription

idstring

namestring

codestringThe SKU. Unique within the shop.

descriptionstringThe long description, as HTML.

description\_typestringWhich editor the description was written with.

publishedboolean

quantityinteger`-1` when this product does not track stock, which is not the same as `0`.

msrpintegerThe manufacturer's suggested price, shown struck through when the shop is configured to.

gtinstringThe barcode: EAN, UPC or ISBN. This is what `GET /products/lookup` matches on.

conditionstringNew, used, refurbished. Used by the feeds rather than by the shop itself.

weightintegerShipping weight, in `weight_unit`.

weight\_unitstring`kg`, `g`, `lb` or `oz`.

widthintegerIn `dimension_unit`.

heightintegerIn `dimension_unit`.

lengthintegerIn `dimension_unit`.

dimension\_unitstring`m`, `cm`, `mm`, `ft` or `in`.

min\_per\_orderintegerThe smallest quantity a customer may order, `0` for no minimum.

max\_per\_orderintegerThe largest, `0` for no maximum.

sale\_startinteger\|nullUnix timestamp before which the product is not on sale.

sale\_endinteger\|nullUnix timestamp after which it is no longer sold.

page\_titlestringSEO title, empty to use the name.

meta\_descriptionstringSEO description.

keywordsstringSEO keywords.

canonicalstringA canonical URL, when this page should point at another.

urlstringThe address of the product page on the shop.

aliasstringThe slug used in that address.

accessobjectWho may see the product: `mode` (`all`, `none` or `groups`) and `groups`, which are user \*\*group\*\* ids and not Joomla view levels. The two id spaces overlap and disagree, so a value that looks plausible can grant the wrong audience.modestring`all`, `none`, or `groups` when it is restricted to some.

groupsinteger\[\]User group ids, meaningful only when the mode is `groups`.

contactbooleanWhether this product is enquired about rather than bought.

warehouse\_idintegerThe warehouse holding the stock, `0` when the shop has none.

typestring`main` for a product, `variant` for one of its variants.

parent\_idintegerThe parent product when this is a variant, `0` otherwise.

value\_idsinteger\[\]For a variant, the characteristic values it stands for.

manufacturer\_idintegerThe brand, `0` when unset.

manufacturer\_namestringIts name, saving a second call.

tax\_idintegerThe tax category, `0` when the product is untaxed.

tax\_namestringIts name.

tax\_ratenumberThe rate as a fraction, so `0.2` is twenty percent.

pricesobject\[\]Every price row, including the restricted ones. A product with none is not sellable.idstring

valuestringTax excluded, as stored.

currency\_idstring

min\_quantitystringFrom how many items this row applies, which is how quantity breaks are expressed.

accessobjectWho this price is for, in the same shape as the product access.modestringAs above.

groupsinteger\[\]As above.

usersinteger\[\]Named customers, empty for everyone.

zone\_idsinteger\[\]Zones this price applies in, empty for everywhere.

start\_dateinteger\|nullUnix timestamp.

end\_dateinteger\|nullUnix timestamp.

imagesobject\[\]In the order the editor shows them; the first is the main image.idstring

namestring

pathstringRelative to the upload folder.

urlstringAbsolute, ready to display.

orderingstring

descriptionstringThe alt text.

accessobjectWho may see it.modestringAs above.

groupsinteger\[\]As above.

free\_downloadstringFiles only; meaningless on an image.

filesobject\[\]Downloadable files, in the same shape as the images.idstring

namestring

pathstringRelative to the upload folder.

urlstringAbsolute.

orderingstring

descriptionstring

accessobjectWho may download it.

free\_downloadstringWhether it can be downloaded without buying the product.

categoriesobject\[\]The categories the product is in.idinteger

namestring

bundleobject\[\]The products this one is made of, when it is a bundle.idstring

namestring

codestring

quantitystringHow many of it the bundle contains.

optionsobject\[\]Products offered as options alongside this one.idstring

namestring

codestring

quantitystring

relatedobject\[\]Products shown as related.idstring

namestring

codestring

quantitystring

tagsinteger\[\]CMS tag ids.

characteristicsobject\[\]The characteristics this product varies on. Empty when it has no variants.idintegerThe characteristic, such as Size.

namestringIts name.

valuesobject\[\]The values of it this product uses, such as S, M and L.idintegerThe value id, which is what a variant refers to.

valuestringIts name, such as `M`.

variantsobject\[\]Every variant, with its own code, stock, price and images. Empty for a product that does not vary.idintegerThe variant is a product in its own right, and this is its id.

codestringIts own SKU.

quantityintegerIts own stock. This is the figure to change, not the parent's.

publishedboolean

pricenumber\|null`null` when the variant has no price of its own and the parent's applies.

valuesobject\[\]Which characteristic values this variant stands for, one per characteristic.option\_idintegerThe characteristic.

option\_namestringIts name, so the variant can be labelled without a second call.

value\_idintegerThe value.

valuestringIts name.

imagesobject\[\]The variant's own images, in the same shape as the product's.idinteger

namestring

pathstringRelative to the upload folder.

urlstringAbsolute.

orderinginteger

fieldsobject\[\]The definitions of the custom fields that apply to this product, so a client can build a form for them.namekeystringThe key used in `custom_fields`.

typestring`text`, `radio`, `singledropdown`, `file`, and the rest of HikaShop's field types.

raw\_typestringHikaShop's own name for the type, before it is mapped to something a client can render.

labelstringTranslated into the operator's language.

defaultstringThe value used when none is given.

requiredbooleanWhether the shop refuses to save the product without it.

optionsobject\[\]The choices, for a field that has them. Empty for a free text one.

multiplebooleanWhether more than one choice may be selected.

translatablebooleanWhether its value can be translated, which is what the translation routes offer.

upload\_dirstringFor a file field, where its uploads are kept.

allowed\_extensionsstringFor a file field, the extensions it accepts, comma separated. Empty means the shop default.

date\_formatstringFor a date field, the format it is stored in.

custom\_fieldsobjectTheir values, keyed by namekey. The keys depend on the shop; `fields` says what they are.

custom\_field\_filesobjectFor custom fields holding a file, the file behind each value. Keyed the same way.

sectionsobject\[\]Information other plugins show on this record, each with a `key`, a `title` and `rows` (`label`, `value`, and optionally `url`, `badge` and `ref`). Empty when no plugin adds any; on a customer, core adds their paid downloads. See the guide on adding information and settings.

extensionsobject\[\]Settings other plugins keep on this record, in groups (`key`, `title`, `fields`), each field described like a custom field plus its current `value`. Send changes back as `extensions` with the record's save. Empty when no plugin adds any.

### Errors

CodeHTTPMeans

invalid\_fields400One of your own fields was rejected by its own rules.

save\_failed500The shop refused to save the product.

```
curl -X POST "$SHOP/hikashop-api/v1/products" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Documentation capture product",
    "code": "DOC-CAPTURE-1"
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">9149</span>,
        <span class="k">"name"</span>: <span class="s">"Documentation capture product"</span>,
        <span class="k">"code"</span>: <span class="s">"DOC-CAPTURE-1"</span>,
        <span class="k">"description"</span>: <span class="s">""</span>,
        <span class="k">"description_type"</span>: <span class="s">""</span>,
        <span class="k">"published"</span>: <span class="n">false</span>,
        <span class="k">"quantity"</span>: <span class="n">-1</span>,
        <span class="k">"msrp"</span>: <span class="n">0</span>,
        <span class="k">"gtin"</span>: <span class="s">""</span>,
        <span class="k">"condition"</span>: <span class="s">""</span>,
        <span class="k">"weight"</span>: <span class="n">0</span>,
        <span class="k">"weight_unit"</span>: <span class="s">"kg"</span>,
        <span class="k">"width"</span>: <span class="n">0</span>,
        <span class="k">"height"</span>: <span class="n">0</span>,
        <span class="k">"length"</span>: <span class="n">0</span>,
        <span class="k">"dimension_unit"</span>: <span class="s">"m"</span>,
        <span class="k">"min_per_order"</span>: <span class="n">0</span>,
        <span class="k">"max_per_order"</span>: <span class="n">0</span>,
        <span class="k">"sale_start"</span>: <span class="n">0</span>,
        <span class="k">"sale_end"</span>: <span class="n">0</span>,
        <span class="k">"page_title"</span>: <span class="s">""</span>,
        <span class="k">"meta_description"</span>: <span class="s">""</span>,
        <span class="k">"keywords"</span>: <span class="s">""</span>,
        <span class="k">"canonical"</span>: <span class="s">""</span>,
        <span class="k">"url"</span>: <span class="s">""</span>,
        <span class="k">"alias"</span>: <span class="s">"documentation-capture-product"</span>,
        <span class="k">"access"</span>: {
            <span class="k">"mode"</span>: <span class="s">"all"</span>,
            <span class="k">"groups"</span>: []
        },
        <span class="k">"contact"</span>: <span class="n">false</span>,
        <span class="k">"warehouse_id"</span>: <span class="n">0</span>,
        <span class="k">"type"</span>: <span class="s">"main"</span>,
        <span class="k">"parent_id"</span>: <span class="n">0</span>,
        <span class="k">"value_ids"</span>: [],
        <span class="k">"manufacturer_id"</span>: <span class="n">0</span>,
        <span class="k">"manufacturer_name"</span>: <span class="s">""</span>,
        <span class="k">"tax_id"</span>: <span class="n">0</span>,
        <span class="k">"tax_name"</span>: <span class="s">""</span>,
        <span class="k">"tax_rate"</span>: <span class="n">0</span>,
        <span class="k">"prices"</span>: [],
        <span class="k">"images"</span>: [],
        <span class="k">"files"</span>: [],
        <span class="k">"categories"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">2</span>,
                <span class="k">"name"</span>: <span class="s">"product category"</span>
            }
        ],
        <span class="k">"bundle"</span>: [],
        <span class="k">"options"</span>: [],
        <span class="k">"related"</span>: [],
        <span class="k">"tags"</span>: [],
        <span class="k">"characteristics"</span>: [],
        <span class="k">"variants"</span>: [],
        <span class="k">"fields"</span>: [
            {
                <span class="k">"namekey"</span>: <span class="s">"test_ajax_image"</span>,
                <span class="k">"type"</span>: <span class="s">"ajaximage"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"ajaximage"</span>,
                <span class="k">"label"</span>: <span class="s">"Test Ajax Image"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">false</span>,
                <span class="k">"options"</span>: [],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            },
            {
                <span class="k">"namekey"</span>: <span class="s">"product_gtin"</span>,
                <span class="k">"type"</span>: <span class="s">"text"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"text"</span>,
                <span class="k">"label"</span>: <span class="s">"GTIN"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">false</span>,
                <span class="k">"options"</span>: [],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            }
        ],
        <span class="k">"custom_fields"</span>: {
            <span class="k">"test_ajax_image"</span>: <span class="n">null</span>,
            <span class="k">"product_gtin"</span>: <span class="n">null</span>
        },
        <span class="k">"custom_field_files"</span>: {
            <span class="k">"test_ajax_image"</span>: []
        },
        <span class="k">"sections"</span>: [],
        <span class="k">"extensions"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Update a product

PUT /products/**{id}** write since 6.6.0

Changes the fields you send and leaves the rest alone, which is the opposite of the price and category calls: this one merges.

Sending nothing to change is refused rather than treated as a success, so a client cannot believe it saved something it did not.

### Path

ParameterTypeDescription

idrequiredintegerThe product or variant.

### Body

The same fields as `POST /products`, all of them optional here. A field you do not send keeps its value; `access` and `custom_fields` are accepted too, and `extensions` for other plugins' settings (`{ group key: { namekey: value } }`, saved after the product's own fields; see the guide on adding information and settings).

### Response expand all

FieldTypeDescription

idstring

namestring

codestringThe SKU. Unique within the shop.

descriptionstringThe long description, as HTML.

description\_typestringWhich editor the description was written with.

publishedboolean

quantityinteger`-1` when this product does not track stock, which is not the same as `0`.

msrpintegerThe manufacturer's suggested price, shown struck through when the shop is configured to.

gtinstringThe barcode: EAN, UPC or ISBN. This is what `GET /products/lookup` matches on.

conditionstringNew, used, refurbished. Used by the feeds rather than by the shop itself.

weightintegerShipping weight, in `weight_unit`.

weight\_unitstring`kg`, `g`, `lb` or `oz`.

widthintegerIn `dimension_unit`.

heightintegerIn `dimension_unit`.

lengthintegerIn `dimension_unit`.

dimension\_unitstring`m`, `cm`, `mm`, `ft` or `in`.

min\_per\_orderintegerThe smallest quantity a customer may order, `0` for no minimum.

max\_per\_orderintegerThe largest, `0` for no maximum.

sale\_startinteger\|nullUnix timestamp before which the product is not on sale.

sale\_endinteger\|nullUnix timestamp after which it is no longer sold.

page\_titlestringSEO title, empty to use the name.

meta\_descriptionstringSEO description.

keywordsstringSEO keywords.

canonicalstringA canonical URL, when this page should point at another.

urlstringThe address of the product page on the shop.

aliasstringThe slug used in that address.

accessobjectWho may see the product: `mode` (`all`, `none` or `groups`) and `groups`, which are user \*\*group\*\* ids and not Joomla view levels. The two id spaces overlap and disagree, so a value that looks plausible can grant the wrong audience.modestring`all`, `none`, or `groups` when it is restricted to some.

groupsinteger\[\]User group ids, meaningful only when the mode is `groups`.

contactbooleanWhether this product is enquired about rather than bought.

warehouse\_idintegerThe warehouse holding the stock, `0` when the shop has none.

typestring`main` for a product, `variant` for one of its variants.

parent\_idintegerThe parent product when this is a variant, `0` otherwise.

value\_idsinteger\[\]For a variant, the characteristic values it stands for.

manufacturer\_idintegerThe brand, `0` when unset.

manufacturer\_namestringIts name, saving a second call.

tax\_idintegerThe tax category, `0` when the product is untaxed.

tax\_namestringIts name.

tax\_ratenumberThe rate as a fraction, so `0.2` is twenty percent.

pricesobject\[\]Every price row, including the restricted ones. A product with none is not sellable.idinteger

valuenumberTax excluded, as stored.

currency\_idinteger

min\_quantityintegerFrom how many items this row applies, which is how quantity breaks are expressed.

accessobjectWho this price is for, in the same shape as the product access.modestringAs above.

groupsinteger\[\]As above.

usersinteger\[\]Named customers, empty for everyone.

zone\_idsinteger\[\]Zones this price applies in, empty for everywhere.

start\_dateinteger\|nullUnix timestamp.

end\_dateinteger\|nullUnix timestamp.

imagesobject\[\]In the order the editor shows them; the first is the main image.idinteger

namestring

pathstringRelative to the upload folder.

urlstringAbsolute, ready to display.

orderinginteger

descriptionstringThe alt text.

accessobjectWho may see it.modestringAs above.

groupsinteger\[\]As above.

free\_downloadbooleanFiles only; meaningless on an image.

filesobject\[\]Downloadable files, in the same shape as the images.idstring

namestring

pathstringRelative to the upload folder.

urlstringAbsolute.

orderingstring

descriptionstring

accessobjectWho may download it.

free\_downloadstringWhether it can be downloaded without buying the product.

categoriesobject\[\]The categories the product is in.idinteger

namestring

bundleobject\[\]The products this one is made of, when it is a bundle.idstring

namestring

codestring

quantitystringHow many of it the bundle contains.

optionsobject\[\]Products offered as options alongside this one.idstring

namestring

codestring

quantitystring

relatedobject\[\]Products shown as related.idstring

namestring

codestring

quantitystring

tagsinteger\[\]CMS tag ids.

characteristicsobject\[\]The characteristics this product varies on. Empty when it has no variants.idintegerThe characteristic, such as Size.

namestringIts name.

valuesobject\[\]The values of it this product uses, such as S, M and L.idintegerThe value id, which is what a variant refers to.

valuestringIts name, such as `M`.

variantsobject\[\]Every variant, with its own code, stock, price and images. Empty for a product that does not vary.idintegerThe variant is a product in its own right, and this is its id.

codestringIts own SKU.

quantityintegerIts own stock. This is the figure to change, not the parent's.

publishedboolean

pricenumber\|null`null` when the variant has no price of its own and the parent's applies.

valuesobject\[\]Which characteristic values this variant stands for, one per characteristic.option\_idintegerThe characteristic.

option\_namestringIts name, so the variant can be labelled without a second call.

value\_idintegerThe value.

valuestringIts name.

imagesobject\[\]The variant's own images, in the same shape as the product's.idinteger

namestring

pathstringRelative to the upload folder.

urlstringAbsolute.

orderinginteger

fieldsobject\[\]The definitions of the custom fields that apply to this product, so a client can build a form for them.namekeystringThe key used in `custom_fields`.

typestring`text`, `radio`, `singledropdown`, `file`, and the rest of HikaShop's field types.

raw\_typestringHikaShop's own name for the type, before it is mapped to something a client can render.

labelstringTranslated into the operator's language.

defaultstringThe value used when none is given.

requiredbooleanWhether the shop refuses to save the product without it.

optionsobject\[\]The choices, for a field that has them. Empty for a free text one.

multiplebooleanWhether more than one choice may be selected.

translatablebooleanWhether its value can be translated, which is what the translation routes offer.

upload\_dirstringFor a file field, where its uploads are kept.

allowed\_extensionsstringFor a file field, the extensions it accepts, comma separated. Empty means the shop default.

date\_formatstringFor a date field, the format it is stored in.

custom\_fieldsobjectTheir values, keyed by namekey. The keys depend on the shop; `fields` says what they are.

custom\_field\_filesobjectFor custom fields holding a file, the file behind each value. Keyed the same way.

sectionsobject\[\]Information other plugins show on this record, each with a `key`, a `title` and `rows` (`label`, `value`, and optionally `url`, `badge` and `ref`). Empty when no plugin adds any; on a customer, core adds their paid downloads. See the guide on adding information and settings.

extensionsobject\[\]Settings other plugins keep on this record, in groups (`key`, `title`, `fields`), each field described like a custom field plus its current `value`. Send changes back as `extensions` with the record's save. Empty when no plugin adds any.

### Errors

CodeHTTPMeans

not\_found404No such product, or the operator may not change it.

invalid\_fields400One of your own fields was rejected by its own rules.

nothing400The body held no field this shop knows, so nothing would have been written.

invalid\_extensions400The product was saved, but a plugin refused some of its values: &#96;error.details&#96; says which, as &#96;{ group key: { namekey: message } }&#96;.

```
curl -X PUT "$SHOP/hikashop-api/v1/products/{id}" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Desk lamp, brass"
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">9136</span>,
        <span class="k">"name"</span>: <span class="s">"Desk lamp, brass"</span>,
        <span class="k">"code"</span>: <span class="s">"HS-TEST-27025"</span>,
        <span class="k">"description"</span>: <span class="s">""</span>,
        <span class="k">"description_type"</span>: <span class="s">""</span>,
        <span class="k">"published"</span>: <span class="n">false</span>,
        <span class="k">"quantity"</span>: <span class="n">-1</span>,
        <span class="k">"msrp"</span>: <span class="n">0</span>,
        <span class="k">"gtin"</span>: <span class="s">""</span>,
        <span class="k">"condition"</span>: <span class="s">""</span>,
        <span class="k">"weight"</span>: <span class="n">0</span>,
        <span class="k">"weight_unit"</span>: <span class="s">"kg"</span>,
        <span class="k">"width"</span>: <span class="n">0</span>,
        <span class="k">"height"</span>: <span class="n">0</span>,
        <span class="k">"length"</span>: <span class="n">0</span>,
        <span class="k">"dimension_unit"</span>: <span class="s">"m"</span>,
        <span class="k">"min_per_order"</span>: <span class="n">0</span>,
        <span class="k">"max_per_order"</span>: <span class="n">0</span>,
        <span class="k">"sale_start"</span>: <span class="n">0</span>,
        <span class="k">"sale_end"</span>: <span class="n">0</span>,
        <span class="k">"page_title"</span>: <span class="s">""</span>,
        <span class="k">"meta_description"</span>: <span class="s">""</span>,
        <span class="k">"keywords"</span>: <span class="s">""</span>,
        <span class="k">"canonical"</span>: <span class="s">""</span>,
        <span class="k">"url"</span>: <span class="s">""</span>,
        <span class="k">"alias"</span>: <span class="s">"desk-lamp-brass"</span>,
        <span class="k">"access"</span>: {
            <span class="k">"mode"</span>: <span class="s">"all"</span>,
            <span class="k">"groups"</span>: []
        },
        <span class="k">"contact"</span>: <span class="n">false</span>,
        <span class="k">"warehouse_id"</span>: <span class="n">0</span>,
        <span class="k">"type"</span>: <span class="s">"main"</span>,
        <span class="k">"parent_id"</span>: <span class="n">0</span>,
        <span class="k">"value_ids"</span>: [],
        <span class="k">"manufacturer_id"</span>: <span class="n">0</span>,
        <span class="k">"manufacturer_name"</span>: <span class="s">""</span>,
        <span class="k">"tax_id"</span>: <span class="n">0</span>,
        <span class="k">"tax_name"</span>: <span class="s">""</span>,
        <span class="k">"tax_rate"</span>: <span class="n">0</span>,
        <span class="k">"prices"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">4947</span>,
                <span class="k">"value"</span>: <span class="n">19.9</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>,
                <span class="k">"min_quantity"</span>: <span class="n">1</span>,
                <span class="k">"access"</span>: {
                    <span class="k">"mode"</span>: <span class="s">"all"</span>,
                    <span class="k">"groups"</span>: []
                },
                <span class="k">"users"</span>: [],
                <span class="k">"zone_ids"</span>: [],
                <span class="k">"start_date"</span>: <span class="n">0</span>,
                <span class="k">"end_date"</span>: <span class="n">0</span>
            }
        ],
        <span class="k">"images"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">8333</span>,
                <span class="k">"name"</span>: <span class="s">"documentation-capture.png"</span>,
                <span class="k">"path"</span>: <span class="s">"documentation-capture.png"</span>,
                <span class="k">"url"</span>: <span class="s">"http://localhost:<span class="n">8080</span>/joomla6_ext/images/com_hikashop/upload/documentation-capture.png"</span>,
                <span class="k">"ordering"</span>: <span class="n">1</span>,
                <span class="k">"description"</span>: <span class="s">"A one pixel image"</span>,
                <span class="k">"access"</span>: {
                    <span class="k">"mode"</span>: <span class="s">"all"</span>,
                    <span class="k">"groups"</span>: []
                },
                <span class="k">"free_download"</span>: <span class="n">false</span>
            }
        ],
        <span class="k">"files"</span>: [],
        <span class="k">"categories"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">2</span>,
                <span class="k">"name"</span>: <span class="s">"product category"</span>
            }
        ],
        <span class="k">"bundle"</span>: [],
        <span class="k">"options"</span>: [],
        <span class="k">"related"</span>: [],
        <span class="k">"tags"</span>: [],
        <span class="k">"characteristics"</span>: [],
        <span class="k">"variants"</span>: [],
        <span class="k">"fields"</span>: [
            {
                <span class="k">"namekey"</span>: <span class="s">"test_ajax_image"</span>,
                <span class="k">"type"</span>: <span class="s">"ajaximage"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"ajaximage"</span>,
                <span class="k">"label"</span>: <span class="s">"Test Ajax Image"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">false</span>,
                <span class="k">"options"</span>: [],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            },
            {
                <span class="k">"namekey"</span>: <span class="s">"product_gtin"</span>,
                <span class="k">"type"</span>: <span class="s">"text"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"text"</span>,
                <span class="k">"label"</span>: <span class="s">"GTIN"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">false</span>,
                <span class="k">"options"</span>: [],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            }
        ],
        <span class="k">"custom_fields"</span>: {
            <span class="k">"test_ajax_image"</span>: <span class="n">null</span>,
            <span class="k">"product_gtin"</span>: <span class="n">null</span>
        },
        <span class="k">"custom_field_files"</span>: {
            <span class="k">"test_ajax_image"</span>: []
        },
        <span class="k">"sections"</span>: [],
        <span class="k">"extensions"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Delete a product

DELETE /products/**{id}** write since 6.6.0

Deletes a product and its variants.

Orders that already contain it are untouched: an order line records what was sold at the time, and it does not stop meaning something because the catalogue changed.

### Path

ParameterTypeDescription

idrequiredintegerThe product.

### Response expand all

FieldTypeDescription

idintegerThe product that was deleted.

deletedbooleanTrue when the row is gone.

### Errors

CodeHTTPMeans

not\_found404No such product, or the operator may not delete it.

delete\_failed400The shop refused to delete it.

```
curl -X DELETE "$SHOP/hikashop-api/v1/products/{id}" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">9136</span>,
        <span class="k">"deleted"</span>: <span class="n">true</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Reconcile the variant set

PUT /products/**{id}**/variants write since 6.6.0

Takes the variants a product should have and makes the shop agree: it creates the ones that are missing, updates the ones that exist and removes the ones you left out.

A variant is identified by the characteristic values it stands for rather than by an id, because that is what makes it that variant. Send the whole set.

### Path

ParameterTypeDescription

idrequiredintegerThe parent product.

### Body

FieldTypeDescription

variantsrequiredobject\[\]The complete set. Each needs the characteristic `values` it stands for, and may carry `code`, `quantity`, `published` and `price`.

### Response expand all

FieldTypeDescription

characteristicsobject\[\]The characteristics the product now varies on, as they stand after the change.

variantsobject\[\]The variants as they now stand, in the same shape as on the product.

### Errors

CodeHTTPMeans

not\_found404No such product, or the operator may not change it.

```
curl -X PUT "$SHOP/hikashop-api/v1/products/{id}/variants" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "variants": []
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"characteristics"</span>: [],
        <span class="k">"variants"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Edit one variant

PUT /products/**{id}**/variants/**{vid}** write since 6.6.0

Changes one variant without touching the others, which is what a stock correction or a price change on a single size needs.

### Path

ParameterTypeDescription

idrequiredintegerThe parent product.

vidrequiredintegerThe variant.

### Body

Any of `code`, `quantity`, `published` and `price`, and your own product fields. What you do not send is left alone.

### Response expand all

FieldTypeDescription

idstring

namestring

codestringThe SKU. Unique within the shop.

descriptionstringThe long description, as HTML.

description\_typestringWhich editor the description was written with.

publishedboolean

quantityinteger`-1` when this product does not track stock, which is not the same as `0`.

msrpintegerThe manufacturer's suggested price, shown struck through when the shop is configured to.

gtinstringThe barcode: EAN, UPC or ISBN. This is what `GET /products/lookup` matches on.

conditionstringNew, used, refurbished. Used by the feeds rather than by the shop itself.

weightintegerShipping weight, in `weight_unit`.

weight\_unitstring`kg`, `g`, `lb` or `oz`.

widthintegerIn `dimension_unit`.

heightintegerIn `dimension_unit`.

lengthintegerIn `dimension_unit`.

dimension\_unitstring`m`, `cm`, `mm`, `ft` or `in`.

min\_per\_orderintegerThe smallest quantity a customer may order, `0` for no minimum.

max\_per\_orderintegerThe largest, `0` for no maximum.

sale\_startinteger\|nullUnix timestamp before which the product is not on sale.

sale\_endinteger\|nullUnix timestamp after which it is no longer sold.

page\_titlestringSEO title, empty to use the name.

meta\_descriptionstringSEO description.

keywordsstringSEO keywords.

canonicalstringA canonical URL, when this page should point at another.

urlstringThe address of the product page on the shop.

aliasstringThe slug used in that address.

accessobjectWho may see the product: `mode` (`all`, `none` or `groups`) and `groups`, which are user \*\*group\*\* ids and not Joomla view levels. The two id spaces overlap and disagree, so a value that looks plausible can grant the wrong audience.modestring`all`, `none`, or `groups` when it is restricted to some.

groupsinteger\[\]User group ids, meaningful only when the mode is `groups`.

contactbooleanWhether this product is enquired about rather than bought.

warehouse\_idintegerThe warehouse holding the stock, `0` when the shop has none.

typestring`main` for a product, `variant` for one of its variants.

parent\_idintegerThe parent product when this is a variant, `0` otherwise.

value\_idsinteger\[\]For a variant, the characteristic values it stands for.

manufacturer\_idintegerThe brand, `0` when unset.

manufacturer\_namestringIts name, saving a second call.

tax\_idintegerThe tax category, `0` when the product is untaxed.

tax\_namestringIts name.

tax\_ratenumberThe rate as a fraction, so `0.2` is twenty percent.

pricesobject\[\]Every price row, including the restricted ones. A product with none is not sellable.idstring

valuestringTax excluded, as stored.

currency\_idstring

min\_quantitystringFrom how many items this row applies, which is how quantity breaks are expressed.

accessobjectWho this price is for, in the same shape as the product access.modestringAs above.

groupsinteger\[\]As above.

usersinteger\[\]Named customers, empty for everyone.

zone\_idsinteger\[\]Zones this price applies in, empty for everywhere.

start\_dateinteger\|nullUnix timestamp.

end\_dateinteger\|nullUnix timestamp.

imagesobject\[\]In the order the editor shows them; the first is the main image.idinteger

namestring

pathstringRelative to the upload folder.

urlstringAbsolute, ready to display.

orderinginteger

descriptionstringThe alt text.

accessobjectWho may see it.modestringAs above.

groupsinteger\[\]As above.

free\_downloadbooleanFiles only; meaningless on an image.

filesobject\[\]Downloadable files, in the same shape as the images.idstring

namestring

pathstringRelative to the upload folder.

urlstringAbsolute.

orderingstring

descriptionstring

accessobjectWho may download it.

free\_downloadstringWhether it can be downloaded without buying the product.

categoriesobject\[\]The categories the product is in.idstring

namestring

bundleobject\[\]The products this one is made of, when it is a bundle.idstring

namestring

codestring

quantitystringHow many of it the bundle contains.

optionsobject\[\]Products offered as options alongside this one.idstring

namestring

codestring

quantitystring

relatedobject\[\]Products shown as related.idstring

namestring

codestring

quantitystring

tagsinteger\[\]CMS tag ids.

characteristicsobject\[\]The characteristics this product varies on. Empty when it has no variants.idintegerThe characteristic, such as Size.

namestringIts name.

valuesobject\[\]The values of it this product uses, such as S, M and L.idintegerThe value id, which is what a variant refers to.

valuestringIts name, such as `M`.

variantsobject\[\]Every variant, with its own code, stock, price and images. Empty for a product that does not vary.idintegerThe variant is a product in its own right, and this is its id.

codestringIts own SKU.

quantityintegerIts own stock. This is the figure to change, not the parent's.

publishedboolean

pricenumber\|null`null` when the variant has no price of its own and the parent's applies.

valuesobject\[\]Which characteristic values this variant stands for, one per characteristic.option\_idintegerThe characteristic.

option\_namestringIts name, so the variant can be labelled without a second call.

value\_idintegerThe value.

valuestringIts name.

imagesobject\[\]The variant's own images, in the same shape as the product's.idinteger

namestring

pathstringRelative to the upload folder.

urlstringAbsolute.

orderinginteger

fieldsobject\[\]The definitions of the custom fields that apply to this product, so a client can build a form for them.namekeystringThe key used in `custom_fields`.

typestring`text`, `radio`, `singledropdown`, `file`, and the rest of HikaShop's field types.

raw\_typestringHikaShop's own name for the type, before it is mapped to something a client can render.

labelstringTranslated into the operator's language.

defaultstringThe value used when none is given.

requiredbooleanWhether the shop refuses to save the product without it.

optionsobject\[\]The choices, for a field that has them. Empty for a free text one.

multiplebooleanWhether more than one choice may be selected.

translatablebooleanWhether its value can be translated, which is what the translation routes offer.

upload\_dirstringFor a file field, where its uploads are kept.

allowed\_extensionsstringFor a file field, the extensions it accepts, comma separated. Empty means the shop default.

date\_formatstringFor a date field, the format it is stored in.

custom\_fieldsobjectTheir values, keyed by namekey. The keys depend on the shop; `fields` says what they are.

custom\_field\_filesobjectFor custom fields holding a file, the file behind each value. Keyed the same way.

sectionsobject\[\]Information other plugins show on this record, each with a `key`, a `title` and `rows` (`label`, `value`, and optionally `url`, `badge` and `ref`). Empty when no plugin adds any; on a customer, core adds their paid downloads. See the guide on adding information and settings.

extensionsobject\[\]Settings other plugins keep on this record, in groups (`key`, `title`, `fields`), each field described like a custom field plus its current `value`. Send changes back as `extensions` with the record's save. Empty when no plugin adds any.

### Errors

CodeHTTPMeans

not\_found404No such variant, or the operator may not change it.

invalid\_fields400One of your own fields was rejected by its own rules.

```
curl -X PUT "$SHOP/hikashop-api/v1/products/{id}/variants/{id}" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "quantity": 7
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">8671</span>,
        <span class="k">"name"</span>: <span class="s">"Waxed Canvas Sandals — XS"</span>,
        <span class="k">"code"</span>: <span class="s">"DEMO-0027-XS"</span>,
        <span class="k">"description"</span>: <span class="s">""</span>,
        <span class="k">"description_type"</span>: <span class="s">""</span>,
        <span class="k">"published"</span>: <span class="n">true</span>,
        <span class="k">"quantity"</span>: <span class="n">7</span>,
        <span class="k">"msrp"</span>: <span class="n">0</span>,
        <span class="k">"gtin"</span>: <span class="s">""</span>,
        <span class="k">"condition"</span>: <span class="s">""</span>,
        <span class="k">"weight"</span>: <span class="n">0</span>,
        <span class="k">"weight_unit"</span>: <span class="s">"kg"</span>,
        <span class="k">"width"</span>: <span class="n">0</span>,
        <span class="k">"height"</span>: <span class="n">0</span>,
        <span class="k">"length"</span>: <span class="n">0</span>,
        <span class="k">"dimension_unit"</span>: <span class="s">"m"</span>,
        <span class="k">"min_per_order"</span>: <span class="n">0</span>,
        <span class="k">"max_per_order"</span>: <span class="n">0</span>,
        <span class="k">"sale_start"</span>: <span class="n">0</span>,
        <span class="k">"sale_end"</span>: <span class="n">0</span>,
        <span class="k">"page_title"</span>: <span class="s">""</span>,
        <span class="k">"meta_description"</span>: <span class="s">""</span>,
        <span class="k">"keywords"</span>: <span class="s">""</span>,
        <span class="k">"canonical"</span>: <span class="s">""</span>,
        <span class="k">"url"</span>: <span class="s">""</span>,
        <span class="k">"alias"</span>: <span class="s">""</span>,
        <span class="k">"access"</span>: {
            <span class="k">"mode"</span>: <span class="s">"all"</span>,
            <span class="k">"groups"</span>: []
        },
        <span class="k">"contact"</span>: <span class="n">false</span>,
        <span class="k">"warehouse_id"</span>: <span class="n">0</span>,
        <span class="k">"type"</span>: <span class="s">"variant"</span>,
        <span class="k">"parent_id"</span>: <span class="n">8670</span>,
        <span class="k">"value_ids"</span>: [
            35
        ],
        <span class="k">"manufacturer_id"</span>: <span class="n">0</span>,
        <span class="k">"manufacturer_name"</span>: <span class="s">""</span>,
        <span class="k">"tax_id"</span>: <span class="n">0</span>,
        <span class="k">"tax_name"</span>: <span class="s">""</span>,
        <span class="k">"tax_rate"</span>: <span class="n">0</span>,
        <span class="k">"prices"</span>: [],
        <span class="k">"images"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">7805</span>,
                <span class="k">"name"</span>: <span class="s">"Waxed Canvas Sandals — XS"</span>,
                <span class="k">"path"</span>: <span class="s">"demo-0027-xs.png"</span>,
                <span class="k">"url"</span>: <span class="s">"http://localhost:<span class="n">8080</span>/joomla6_ext/images/com_hikashop/upload/demo-0027-xs.png"</span>,
                <span class="k">"ordering"</span>: <span class="n">1</span>,
                <span class="k">"description"</span>: <span class="s">""</span>,
                <span class="k">"access"</span>: {
                    <span class="k">"mode"</span>: <span class="s">"all"</span>,
                    <span class="k">"groups"</span>: []
                },
                <span class="k">"free_download"</span>: <span class="n">false</span>
            }
        ],
        <span class="k">"files"</span>: [],
        <span class="k">"categories"</span>: [],
        <span class="k">"bundle"</span>: [],
        <span class="k">"options"</span>: [],
        <span class="k">"related"</span>: [],
        <span class="k">"tags"</span>: [],
        <span class="k">"characteristics"</span>: [],
        <span class="k">"variants"</span>: [],
        <span class="k">"fields"</span>: [
            {
                <span class="k">"namekey"</span>: <span class="s">"test_ajax_image"</span>,
                <span class="k">"type"</span>: <span class="s">"ajaximage"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"ajaximage"</span>,
                <span class="k">"label"</span>: <span class="s">"Test Ajax Image"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">false</span>,
                <span class="k">"options"</span>: [],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            },
            {
                <span class="k">"namekey"</span>: <span class="s">"product_gtin"</span>,
                <span class="k">"type"</span>: <span class="s">"text"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"text"</span>,
                <span class="k">"label"</span>: <span class="s">"GTIN"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">false</span>,
                <span class="k">"options"</span>: [],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            }
        ],
        <span class="k">"custom_fields"</span>: {
            <span class="k">"test_ajax_image"</span>: <span class="n">null</span>,
            <span class="k">"product_gtin"</span>: <span class="n">null</span>
        },
        <span class="k">"custom_field_files"</span>: {
            <span class="k">"test_ajax_image"</span>: []
        },
        <span class="k">"sections"</span>: [],
        <span class="k">"extensions"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Apply a coupon to an order

POST /orders/**{id}**/coupon write since 6.6.0

Applies a coupon by its code and re-totals the order.

The shop validates it again here against this order: its dates, its quota, its minimum, the products in the cart and the customer. A coupon that appears in `GET /coupons` can still be refused for this particular order, which is the point of validating rather than trusting the list.

### Path

ParameterTypeDescription

idrequiredintegerThe order.

### Body

FieldTypeDescription

coderequiredstringThe coupon code, as the customer would type it.

### Response expand all

FieldTypeDescription

idintegerThe order.

feesobjectThe discount, shipping and payment amounts of the order.  discountobjectIts `amount`, its `tax`, the `tax_namekeys` behind that tax, and the coupon `code` when one was used.amountnumberA positive figure, already subtracted from the total.

taxnumberThe tax on it.

tax\_namekeysstring\[\]Which tax rates that came from.

codestringThe coupon code, empty for a discount applied by hand.

shippingobjectThe shipping charge and what carried it.amountnumberTax excluded.

taxnumberThe tax on it.

tax\_namekeysstring\[\]Which tax rates that came from.

methodstringThe plugin that handled it.

method\_namestringAs the merchant named it.

paymentobjectThe payment fee and what took it.amountnumberTax excluded.

taxnumberThe tax on it.

tax\_namekeysstring\[\]Which tax rates that came from.

methodstringThe plugin that took it.

method\_namestringAs the merchant named it.

totalsobjectThe order totalled, so a client need not compute it and disagree with the shop.totalnumberWhat the customer owes, tax included.

discountnumberThe discount applied, as a positive figure already subtracted.

shippingnumberThe shipping charged.

paymentnumberThe payment fee charged.

taxnumberThe tax within the total, not on top of it.

### Errors

CodeHTTPMeans

not\_found404No such order, or the operator may not change it.

invalid\_coupon400No such code, or it does not apply to this order.

save\_failed500The order could not be saved.

```
curl -X POST "$SHOP/hikashop-api/v1/orders/{id}/coupon" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "APPTEST10"
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">5630</span>,
        <span class="k">"fees"</span>: {
            <span class="k">"discount"</span>: {
                <span class="k">"amount"</span>: <span class="n">10</span>,
                <span class="k">"tax"</span>: <span class="n">0</span>,
                <span class="k">"tax_namekeys"</span>: [],
                <span class="k">"code"</span>: <span class="s">"APPTEST10"</span>
            },
            <span class="k">"shipping"</span>: {
                <span class="k">"amount"</span>: <span class="n">6.9</span>,
                <span class="k">"tax"</span>: <span class="n">0</span>,
                <span class="k">"tax_namekeys"</span>: [],
                <span class="k">"method"</span>: <span class="s">"manual"</span>,
                <span class="k">"method_name"</span>: <span class="s">"Vendor 2 only shipping"</span>
            },
            <span class="k">"payment"</span>: {
                <span class="k">"amount"</span>: <span class="n">0</span>,
                <span class="k">"tax"</span>: <span class="n">0</span>,
                <span class="k">"tax_namekeys"</span>: [],
                <span class="k">"method"</span>: <span class="s">"paypalcheckout"</span>,
                <span class="k">"method_name"</span>: <span class="s">"PayPal Checkout Express Test"</span>
            }
        },
        <span class="k">"totals"</span>: {
            <span class="k">"total"</span>: <span class="n">303.92</span>,
            <span class="k">"discount"</span>: <span class="n">10</span>,
            <span class="k">"shipping"</span>: <span class="n">6.9</span>,
            <span class="k">"payment"</span>: <span class="n">0</span>,
            <span class="k">"tax"</span>: <span class="n">0</span>
        }
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Remove the discount from an order

DELETE /orders/**{id}**/coupon write since 6.6.0

Takes the coupon or the hand-applied discount off the order and re-totals it. There is nothing to send.

### Path

ParameterTypeDescription

idrequiredintegerThe order.

### Response expand all

FieldTypeDescription

idintegerThe order.

feesobjectThe discount, shipping and payment amounts of the order.  discountobjectIts `amount`, its `tax`, the `tax_namekeys` behind that tax, and the coupon `code` when one was used.amountnumberA positive figure, already subtracted from the total.

taxnumberThe tax on it.

tax\_namekeysstring\[\]Which tax rates that came from.

codestringThe coupon code, empty for a discount applied by hand.

shippingobjectThe shipping charge and what carried it.amountnumberTax excluded.

taxnumberThe tax on it.

tax\_namekeysstring\[\]Which tax rates that came from.

methodstringThe plugin that handled it.

method\_namestringAs the merchant named it.

paymentobjectThe payment fee and what took it.amountnumberTax excluded.

taxnumberThe tax on it.

tax\_namekeysstring\[\]Which tax rates that came from.

methodstringThe plugin that took it.

method\_namestringAs the merchant named it.

totalsobjectThe order totalled, so a client need not compute it and disagree with the shop.totalnumberWhat the customer owes, tax included.

discountnumberThe discount applied, as a positive figure already subtracted.

shippingnumberThe shipping charged.

paymentnumberThe payment fee charged.

taxnumberThe tax within the total, not on top of it.

### Errors

CodeHTTPMeans

not\_found404No such order, or the operator may not change it.

save\_failed500The order could not be saved.

```
curl -X DELETE "$SHOP/hikashop-api/v1/orders/{id}/coupon" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">5630</span>,
        <span class="k">"fees"</span>: {
            <span class="k">"discount"</span>: {
                <span class="k">"amount"</span>: <span class="n">0</span>,
                <span class="k">"tax"</span>: <span class="n">0</span>,
                <span class="k">"tax_namekeys"</span>: [],
                <span class="k">"code"</span>: <span class="s">""</span>
            },
            <span class="k">"shipping"</span>: {
                <span class="k">"amount"</span>: <span class="n">6.9</span>,
                <span class="k">"tax"</span>: <span class="n">0</span>,
                <span class="k">"tax_namekeys"</span>: [],
                <span class="k">"method"</span>: <span class="s">"manual"</span>,
                <span class="k">"method_name"</span>: <span class="s">"Vendor 2 only shipping"</span>
            },
            <span class="k">"payment"</span>: {
                <span class="k">"amount"</span>: <span class="n">0</span>,
                <span class="k">"tax"</span>: <span class="n">0</span>,
                <span class="k">"tax_namekeys"</span>: [],
                <span class="k">"method"</span>: <span class="s">"paypalcheckout"</span>,
                <span class="k">"method_name"</span>: <span class="s">"PayPal Checkout Express Test"</span>
            }
        },
        <span class="k">"totals"</span>: {
            <span class="k">"total"</span>: <span class="n">313.92</span>,
            <span class="k">"discount"</span>: <span class="n">0</span>,
            <span class="k">"shipping"</span>: <span class="n">6.9</span>,
            <span class="k">"payment"</span>: <span class="n">0</span>,
            <span class="k">"tax"</span>: <span class="n">0</span>
        }
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Add a line to an order

POST /orders/**{id}**/products write since 6.6.0

Adds a product to an existing order and re-totals it.

Send a `price` only to override what the shop would charge; leave it out and the order's own pricing applies, which is what `GET /orders/{id}/products/precompute` shows you beforehand.

### Path

ParameterTypeDescription

idrequiredintegerThe order.

### Body

FieldTypeDescription

product\_idrequiredintegerThe product or variant to add.

quantityintegerHow many. Defaults to `1`.

pricenumberUnit price, tax excluded, to override the shop. Omit to let the shop price it.

tax\_namekeysstring\[\]Which tax rates to apply, when overriding the price. Omit to let the shop decide.

### Response expand all

FieldTypeDescription

idintegerThe order.

itemsobject\[\]The lines as they now stand, in the same shape as on the order.idintegerThe line id, which is what the line routes take. It is not the product id.

namestringThe product as it was named when ordered.

codestringIts SKU at the time.

quantityinteger

pricenumberUnit price, tax excluded, as agreed at the time.

taxnumberTax on the line.

editablebooleanFalse once the line can no longer be changed.

totalsobjectThe order totalled, so a client need not compute it and disagree with the shop.totalnumberWhat the customer owes, tax included.

discountnumberThe discount applied, as a positive figure already subtracted.

shippingnumberThe shipping charged.

paymentnumberThe payment fee charged.

taxnumberThe tax within the total, not on top of it.

### Errors

CodeHTTPMeans

not\_found404No such order or product, or the operator may not change the order.

save\_failed500The order could not be saved.

```
curl -X POST "$SHOP/hikashop-api/v1/orders/{id}/products" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "product_id": "1",
    "quantity": 1
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">5630</span>,
        <span class="k">"items"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">20630</span>,
                <span class="k">"name"</span>: <span class="s">"Nordic Design item"</span>,
                <span class="k">"code"</span>: <span class="s">"SEED-7-44"</span>,
                <span class="k">"quantity"</span>: <span class="n">1</span>,
                <span class="k">"price"</span>: <span class="n">307.02</span>,
                <span class="k">"tax"</span>: <span class="n">0</span>,
                <span class="k">"editable"</span>: <span class="n">true</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">20642</span>,
                <span class="k">"name"</span>: <span class="s">"Test Product (Vendor 2)"</span>,
                <span class="k">"code"</span>: <span class="s">"TEST001"</span>,
                <span class="k">"quantity"</span>: <span class="n">1</span>,
                <span class="k">"price"</span>: <span class="n">0</span>,
                <span class="k">"tax"</span>: <span class="n">0</span>,
                <span class="k">"editable"</span>: <span class="n">true</span>
            }
        ],
        <span class="k">"totals"</span>: {
            <span class="k">"total"</span>: <span class="n">313.92</span>,
            <span class="k">"discount"</span>: <span class="n">0</span>,
            <span class="k">"shipping"</span>: <span class="n">6.9</span>,
            <span class="k">"payment"</span>: <span class="n">0</span>,
            <span class="k">"tax"</span>: <span class="n">0</span>
        }
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Change a line's quantity

PUT /orders/**{id}**/products/**{lineId}** write since 6.6.0

Changes how many of one line the order holds, and re-totals it. A quantity of `0` removes the line.

The id in the path is the **line** id from `items`, not the product id: the same product can appear on an order more than once.

### Path

ParameterTypeDescription

idrequiredintegerThe order.

lineIdrequiredintegerThe line, from &#96;items\[\].id&#96; on the order.

### Body

FieldTypeDescription

quantityrequiredintegerThe new quantity. `0` removes the line.

### Response expand all

FieldTypeDescription

idintegerThe order.

itemsobject\[\]The lines as they now stand.idintegerThe line id, which is what the line routes take. It is not the product id.

namestringThe product as it was named when ordered.

codestringIts SKU at the time.

quantityinteger

pricenumberUnit price, tax excluded, as agreed at the time.

taxnumberTax on the line.

editablebooleanFalse once the line can no longer be changed.

totalsobjectThe order totalled, so a client need not compute it and disagree with the shop.totalnumberWhat the customer owes, tax included.

discountnumberThe discount applied, as a positive figure already subtracted.

shippingnumberThe shipping charged.

paymentnumberThe payment fee charged.

taxnumberThe tax within the total, not on top of it.

### Errors

CodeHTTPMeans

not\_found404No such order or line, or the operator may not change it.

save\_failed500The order could not be saved.

```
curl -X PUT "$SHOP/hikashop-api/v1/orders/{id}/products/{id}" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "quantity": 2
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">5630</span>,
        <span class="k">"items"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">20630</span>,
                <span class="k">"name"</span>: <span class="s">"Nordic Design item"</span>,
                <span class="k">"code"</span>: <span class="s">"SEED-7-44"</span>,
                <span class="k">"quantity"</span>: <span class="n">1</span>,
                <span class="k">"price"</span>: <span class="n">307.02</span>,
                <span class="k">"tax"</span>: <span class="n">0</span>,
                <span class="k">"editable"</span>: <span class="n">true</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">20642</span>,
                <span class="k">"name"</span>: <span class="s">"Test Product (Vendor 2)"</span>,
                <span class="k">"code"</span>: <span class="s">"TEST001"</span>,
                <span class="k">"quantity"</span>: <span class="n">2</span>,
                <span class="k">"price"</span>: <span class="n">0</span>,
                <span class="k">"tax"</span>: <span class="n">0</span>,
                <span class="k">"editable"</span>: <span class="n">true</span>
            }
        ],
        <span class="k">"totals"</span>: {
            <span class="k">"total"</span>: <span class="n">313.92</span>,
            <span class="k">"discount"</span>: <span class="n">0</span>,
            <span class="k">"shipping"</span>: <span class="n">6.9</span>,
            <span class="k">"payment"</span>: <span class="n">0</span>,
            <span class="k">"tax"</span>: <span class="n">0</span>
        }
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Run a mass action

POST /massactions/**{id}** write since 6.6.0

Runs one of the merchant's own bulk operations over a selection.

It runs the same code the backend runs, so whatever the action does there it does here, including whatever a third-party plugin added to it. Give it the ids to work on.

### Path

ParameterTypeDescription

idrequiredintegerThe mass action, from &#96;GET /massactions&#96;.

### Body

FieldTypeDescription

idsrequiredinteger\[\]The records to run it over, from the listing the action belongs to.

### Response expand all

FieldTypeDescription

okbooleanWhether the action reported success.

countintegerHow many records it worked on.

reportstringWhatever the action had to say, ready to show. Its wording is the action's own.

### Errors

CodeHTTPMeans

invalid\_request400No ids were sent, or the action is not one this shop has.

forbidden403The operator may not work on that kind of record.

```
curl -X POST "$SHOP/hikashop-api/v1/massactions/2" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "ids": [
        "9135"
    ]
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"ok"</span>: <span class="n">true</span>,
        <span class="k">"count"</span>: <span class="n">1</span>,
        <span class="k">"report"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Create an order by hand

POST /orders write since 6.6.0

Creates an empty order for a customer, to be filled in with lines, fees and an address.

Give it either an existing `user_id` or a `guest` with at least an email address, which is how an order gets taken over the telephone from somebody who has never bought before.

### Body

FieldTypeDescription

user\_idintegerAn existing customer. Give this or `guest`.

guestobjectA new guest customer, needing at least `email` and usually a name.

### Response expand all

FieldTypeDescription

idintegerThe order that was created, to add lines to.

### Errors

CodeHTTPMeans

no\_customer400Neither a user\_id nor a usable guest was given.

save\_failed500The order could not be created.

```
curl -X POST "$SHOP/hikashop-api/v1/orders" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "guest": {
        "email": "<joomla-hidden-mail base="" first="YnV5ZXI=" is-email="1" is-link="1" last="ZXhhbXBsZS50ZXN0" text="YnV5ZXJAZXhhbXBsZS50ZXN0">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>",
        "name": "Alex Marchand"
    }
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">5648</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Save an order's custom fields

PUT /orders/**{id}**/fields write since 6.6.0

Writes the merchant's own order fields. Only the fields you send are touched.

### Path

ParameterTypeDescription

idrequiredintegerThe order.

### Body

FieldTypeDescription

fieldsobjectKeyed by field namekey. May be left out when only `extensions` are sent.

extensionsobjectSettings other plugins keep on this record, as `{ group key: { namekey: value } }`, for the groups and fields its `extensions` lists. Saved after the record's own fields. See the guide on adding information and settings.

### Response expand all

FieldTypeDescription

idintegerThe order.

custom\_fieldsobjectThe values as they now stand. The keys depend on the shop.

custom\_field\_filesobjectFor a field holding a file, the file behind the value. Keyed the same way.

extensionsobject\[\]The other plugins' settings on the order as they now stand, as in `GET /orders/{id}`.

### Errors

CodeHTTPMeans

not\_found404No such order, or the operator may not change it.

invalid\_fields400A field was rejected by its own rules.

save\_failed500The order could not be saved.

invalid\_extensions400The record's own fields were saved, but a plugin refused some of its values: &#96;error.details&#96; says which, as &#96;{ group key: { namekey: message } }&#96;.

```
curl -X PUT "$SHOP/hikashop-api/v1/orders/{id}/fields" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "fields": []
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">5630</span>,
        <span class="k">"custom_fields"</span>: {
            <span class="k">"hstestfile1755"</span>: <span class="n">null</span>,
            <span class="k">"hstestfile1859"</span>: <span class="n">null</span>,
            <span class="k">"hstestfile26994"</span>: <span class="n">null</span>,
            <span class="k">"hstestfile28016"</span>: <span class="n">null</span>,
            <span class="k">"hstestfile27610"</span>: <span class="n">null</span>
        },
        <span class="k">"custom_field_files"</span>: {
            <span class="k">"hstestfile1755"</span>: [],
            <span class="k">"hstestfile1859"</span>: [],
            <span class="k">"hstestfile26994"</span>: [],
            <span class="k">"hstestfile28016"</span>: [],
            <span class="k">"hstestfile27610"</span>: []
        },
        <span class="k">"extensions"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Save an address of an order

PUT /orders/**{id}**/address/**{type}** write since 6.6.0

Writes the billing or shipping address of an order, using the fields `GET` gave you.

The address on an order is its own copy, so changing it here does not change the customer's address book, and vice versa. That is deliberate: an invoice should not change because somebody moved.

### Path

ParameterTypeDescription

idrequiredintegerThe order.

typerequiredstring&#96;billing&#96; or &#96;shipping&#96;.

### Body

FieldTypeDescription

fieldsrequiredobjectKeyed by address field namekey, the same keys `GET` returned in `values`.

### Response expand all

FieldTypeDescription

typestringWhich address was written.

address\_idintegerThe address row, created if there was none.

valuesobjectThe values as stored. Keyed by whatever address fields this shop has.

country\_namestringThe country spelled out.

state\_namestringThe state spelled out, empty where the country has none.

summaryobjectThe address ready to show, without re-reading the order.namestring

companystring

formattedobjectLaid out the way this shop lays addresses out, which follows its address format setting.textstringSeveral lines, for an invoice or a label.

one\_linestringOne line, for a list.

streetstring

citystring

post\_codestring

### Errors

CodeHTTPMeans

not\_found404No such order, or the operator may not change it.

invalid\_fields400A field was rejected by its own rules.

invalid\_address400The address is not one the shop will accept, usually a missing required field.

```
curl -X PUT "$SHOP/hikashop-api/v1/orders/{id}/address/billing" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "fields": {
        "address_title": "Mr",
        "address_firstname": "Alex",
        "address_lastname": "Marchand",
        "address_street": "12 rue des Lilas",
        "address_post_code": "44000",
        "address_city": "Nantes",
        "address_telephone": "+33 2 00 00 00 00",
        "address_country": "country_France_73",
        "address_state": "state_Paris_1381"
    }
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"type"</span>: <span class="s">"billing"</span>,
        <span class="k">"address_id"</span>: <span class="n">4385</span>,
        <span class="k">"values"</span>: {
            <span class="k">"address_title"</span>: <span class="s">"Mr"</span>,
            <span class="k">"address_firstname"</span>: <span class="s">"Alex"</span>,
            <span class="k">"address_lastname"</span>: <span class="s">"Marchand"</span>,
            <span class="k">"address_company"</span>: <span class="s">"Lilas SARL"</span>,
            <span class="k">"address_street"</span>: <span class="s">"12 rue des Lilas"</span>,
            <span class="k">"address_post_code"</span>: <span class="s">"44000"</span>,
            <span class="k">"address_city"</span>: <span class="s">"Nantes"</span>,
            <span class="k">"address_telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
            <span class="k">"address_country"</span>: <span class="s">"country_France_73"</span>,
            <span class="k">"address_state"</span>: <span class="s">"state_Paris_1381"</span>,
            <span class="k">"address_vat"</span>: <span class="s">"FR00000000000"</span>
        },
        <span class="k">"country_name"</span>: <span class="s">"France"</span>,
        <span class="k">"state_name"</span>: <span class="s">"Paris"</span>,
        <span class="k">"summary"</span>: {
            <span class="k">"name"</span>: <span class="s">"John Doe"</span>,
            <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
            <span class="k">"formatted"</span>: {
                <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
            },
            <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
            <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
            <span class="k">"post_code"</span>: <span class="s">"44000"</span>
        }
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Attach an image or a file

POST /products/**{id}**/images write since 6.6.0

Adds an image or a downloadable file to a product, either by sending the bytes or by pointing at something already in the upload folder.

Send `data` as base64 to upload, or `path` to attach a file that `GET /media/browse` already showed you. The extension is checked against what the shop allows, so a refusal is the shop's policy rather than a fault.

The same route serves `/images` and `/files`; which one you call decides where it goes.

### Path

ParameterTypeDescription

idrequiredintegerThe product.

### Body

FieldTypeDescription

datastringThe bytes, base64 encoded. Give this or `path`.

pathstringA file already in the upload folder, relative to it, as `GET /media/browse` returns.

namestringThe file name to store it under. Defaults to the one in the path.

descriptionstringThe alt text for an image, or a note on a file.

accessobjectWho may see or download it, in the usual mode and groups shape.

### Response expand all

FieldTypeDescription

idinteger

namestring

pathstringRelative to the upload folder.

urlstringAbsolute, ready to display.

orderingintegerWhere it sits among the others; the first image is the one the shop shows.

descriptionstringThe alt text for an image, or a note on a file.

accessobjectWho may see or download it.modestring`all`, `none`, or `groups` when it is restricted to some.

groupsinteger\[\]User \*\*group\*\* ids, and not Joomla view levels. The two id spaces overlap and disagree, so a value that looks plausible can grant the wrong audience.

free\_downloadbooleanFiles only: whether it can be downloaded without buying the product.

### Errors

CodeHTTPMeans

not\_found404No such product, or the operator may not change it.

bad\_type400The extension is not one this shop accepts.

write\_failed500The upload folder refused the file, which is usually a permissions problem.

```
curl -X POST "$SHOP/hikashop-api/v1/products/{id}/images" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFAAH/q842iQAAAABJRU5ErkJggg==",
    "name": "documentation-capture.png",
    "description": "A one pixel image"
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">8336</span>,
        <span class="k">"name"</span>: <span class="s">"documentation-capture.png"</span>,
        <span class="k">"path"</span>: <span class="s">"documentation-capture.png"</span>,
        <span class="k">"url"</span>: <span class="s">"http://localhost:<span class="n">8080</span>/joomla6_ext/images/com_hikashop/upload/documentation-capture.png"</span>,
        <span class="k">"ordering"</span>: <span class="n">1</span>,
        <span class="k">"description"</span>: <span class="s">"A one pixel image"</span>,
        <span class="k">"access"</span>: {
            <span class="k">"mode"</span>: <span class="s">"all"</span>,
            <span class="k">"groups"</span>: []
        },
        <span class="k">"free_download"</span>: <span class="n">false</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Edit an image or a file

PUT /products/**{id}**/files/**{fileId}** write since 6.6.0

Changes the name, the description or the access of something already attached, without re-uploading the bytes.

### Path

ParameterTypeDescription

idrequiredintegerThe product.

fileIdrequiredintegerThe image or file.

### Body

Any of `name`, `description`, `access` and, for a file, `free_download`. What you do not send is left alone.

### Response expand all

FieldTypeDescription

idinteger

namestring

pathstringRelative to the upload folder.

urlstringAbsolute, ready to display.

orderingintegerWhere it sits among the others; the first image is the one the shop shows.

descriptionstringThe alt text for an image, or a note on a file.

accessobjectWho may see or download it.modestring`all`, `none`, or `groups` when it is restricted to some.

groupsinteger\[\]User \*\*group\*\* ids, and not Joomla view levels. The two id spaces overlap and disagree, so a value that looks plausible can grant the wrong audience.

free\_downloadbooleanFiles only: whether it can be downloaded without buying the product.

### Errors

CodeHTTPMeans

not\_found404No such file on that product, or the operator may not change it.

```
curl -X PUT "$SHOP/hikashop-api/v1/products/{id}/files/{id}" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "documentation-capture.png",
    "description": "A one pixel image"
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">8336</span>,
        <span class="k">"name"</span>: <span class="s">"documentation-capture.png"</span>,
        <span class="k">"path"</span>: <span class="s">"documentation-capture.png"</span>,
        <span class="k">"url"</span>: <span class="s">"http://localhost:<span class="n">8080</span>/joomla6_ext/images/com_hikashop/upload/documentation-capture.png"</span>,
        <span class="k">"ordering"</span>: <span class="n">1</span>,
        <span class="k">"description"</span>: <span class="s">"A one pixel image"</span>,
        <span class="k">"access"</span>: {
            <span class="k">"mode"</span>: <span class="s">"all"</span>,
            <span class="k">"groups"</span>: []
        },
        <span class="k">"free_download"</span>: <span class="n">false</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Remove an image or a file

DELETE /products/**{id}**/files/**{fileId}** write since 6.6.0

Detaches an image or a file from a product.

The bytes stay in the upload folder: another product may be using the same file, and the API will not delete somebody's media because one product stopped pointing at it.

### Path

ParameterTypeDescription

idrequiredintegerThe product.

fileIdrequiredintegerThe image or file.

### Response expand all

FieldTypeDescription

idintegerWhat was detached.

deletedbooleanTrue when the row is gone.

### Errors

CodeHTTPMeans

not\_found404No such file on that product, or the operator may not change it.

```
curl -X DELETE "$SHOP/hikashop-api/v1/products/{id}/files/{id}" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">8337</span>,
        <span class="k">"deleted"</span>: <span class="n">true</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Reorder images and files

PUT /products/**{id}**/media/order write since 6.6.0

Sets the order of a product's images or files. The first image is the one the shop shows, so this is how you choose it.

### Path

ParameterTypeDescription

idrequiredintegerThe product.

### Body

FieldTypeDescription

imagesinteger\[\]File ids in the order you want them.

filesinteger\[\]The same for downloadable files.

### Response expand all

FieldTypeDescription

imagesobject\[\]The images as they now stand, in their new order, each in the same shape as on the product.idinteger

namestring

pathstringRelative to the upload folder.

urlstringAbsolute, ready to display.

orderingintegerWhere it sits among the others; the first image is the one the shop shows.

descriptionstringThe alt text for an image, or a note on a file.

accessobjectWho may see or download it.modestring`all`, `none`, or `groups` when it is restricted to some.

groupsinteger\[\]User \*\*group\*\* ids, and not Joomla view levels. The two id spaces overlap and disagree, so a value that looks plausible can grant the wrong audience.

free\_downloadbooleanFiles only: whether it can be downloaded without buying the product.

filesobject\[\]The files as they now stand, in the same shape as on the product.idinteger

namestring

pathstringRelative to the upload folder.

urlstringAbsolute, ready to display.

orderingintegerWhere it sits among the others; the first image is the one the shop shows.

descriptionstringThe alt text for an image, or a note on a file.

accessobjectWho may see or download it.modestring`all`, `none`, or `groups` when it is restricted to some.

groupsinteger\[\]User \*\*group\*\* ids, and not Joomla view levels. The two id spaces overlap and disagree, so a value that looks plausible can grant the wrong audience.

free\_downloadbooleanFiles only: whether it can be downloaded without buying the product.

### Errors

CodeHTTPMeans

not\_found404No such product, or the operator may not change it.

```
curl -X PUT "$SHOP/hikashop-api/v1/products/{id}/media/order" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "images": [
        7756,
        7757
    ]
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"images"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">7756</span>,
                <span class="k">"name"</span>: <span class="s">"Lacquered Fountain Pen — Broad"</span>,
                <span class="k">"path"</span>: <span class="s">"demo-0002.png"</span>,
                <span class="k">"url"</span>: <span class="s">"http://localhost:<span class="n">8080</span>/joomla6_ext/images/com_hikashop/upload/demo-0002.png"</span>,
                <span class="k">"ordering"</span>: <span class="n">0</span>,
                <span class="k">"description"</span>: <span class="s">""</span>,
                <span class="k">"access"</span>: {
                    <span class="k">"mode"</span>: <span class="s">"all"</span>,
                    <span class="k">"groups"</span>: []
                },
                <span class="k">"free_download"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">7757</span>,
                <span class="k">"name"</span>: <span class="s">"Lacquered Fountain Pen — Broad"</span>,
                <span class="k">"path"</span>: <span class="s">"demo-0002-2.png"</span>,
                <span class="k">"url"</span>: <span class="s">"http://localhost:<span class="n">8080</span>/joomla6_ext/images/com_hikashop/upload/demo-0002-2.png"</span>,
                <span class="k">"ordering"</span>: <span class="n">1</span>,
                <span class="k">"description"</span>: <span class="s">""</span>,
                <span class="k">"access"</span>: {
                    <span class="k">"mode"</span>: <span class="s">"all"</span>,
                    <span class="k">"groups"</span>: []
                },
                <span class="k">"free_download"</span>: <span class="n">false</span>
            }
        ],
        <span class="k">"files"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## The bytes of an image

GET /media/content read since 6.6.0

The bytes of one image from the upload folder, so a client can edit it: crop it, rotate it, and send it back.

This is the one route that does not answer with the envelope. It answers with the file, and with the cross-origin header that lets a browser read it into a canvas, which the shop's own image URLs do not carry. Without it, a web client cannot export an edited image at all.

A path that tries to leave the upload folder is refused rather than resolved.

### Query

ParameterTypeDescription

pathrequiredstringThe image, relative to the upload folder.

### Response

The content of the file requested, with the content type taken from its extension.

### Errors

CodeHTTPMeans

not\_found404No such file, or a path that tried to leave the upload folder.

## Upload the value of a file field

POST /fields/**{table}**/**{namekey}**/file write since 6.6.0

Uploads the file that is the value of one of your own custom fields. Only the two field types that hold one accept it: `ajaximage` and `ajaxfile`.

The field is named rather than numbered, and the table says which kind of record it belongs to, so the same route serves a product field, a category field and a customer field.

### Path

ParameterTypeDescription

tablerequiredstringWhich kind of record: &#96;product&#96;, &#96;category&#96;, &#96;user&#96;, &#96;order&#96;, &#96;address&#96;.

namekeyrequiredstringThe field, as &#96;fields\[\].namekey&#96; gives it.

### Body

FieldTypeDescription

datarequiredstringThe bytes, base64 encoded.

namestringThe file name to store it under.

### Response expand all

FieldTypeDescription

pathstringRelative to the field's own upload folder. This is the value to store on the record.

namestringThe file name it was stored under.

urlstringAbsolute, where the shop serves it from.

### Errors

CodeHTTPMeans

not\_found404No such record kind.

bad\_field400No such field, or it does not hold a file.

bad\_type400The extension is not one this shop accepts.

write\_failed500The upload folder refused the file.

```
curl -X POST "$SHOP/hikashop-api/v1/fields/product/test_ajax_image/file" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFAAH/q842iQAAAABJRU5ErkJggg==",
    "name": "documentation-capture-field.png"
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"path"</span>: <span class="s">"documentation-capture-field_2.png"</span>,
        <span class="k">"name"</span>: <span class="s">"documentation-capture-field_2.png"</span>,
        <span class="k">"url"</span>: <span class="s">"http://localhost:<span class="n">8080</span>/joomla6_ext/images/com_hikashop/upload/documentation-capture-field_2.png"</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## The shipping and payment methods an order can move to

GET /orders/**{id}**/methods read since 6.6.0

What this order could ship and be paid by, with what it uses now, so a change can be offered as a choice rather than as free text.

A method is identified by its plugin and its instance together, written `plugin_id`, which is the pairing the backend posts back. An order that ships from several warehouses carries one method per shipment, and `multiple` says so.

### Path

ParameterTypeDescription

idrequiredintegerThe order.

### Response expand all

FieldTypeDescription

shippingobjectThe shipping choice.currentstringWhat the order uses now, as `plugin_id`. `_` when nothing is set, so the current one always matches an option.

multiplebooleanTrue when the order ships in several shipments and carries a method for each.

optionsobject\[\]What it could move to.valuestringThe `plugin_id` pairing to send when changing the method.

labelstringAs the merchant named it.

groupsobject\[\]For an order that ships in several shipments, the shipments and the method chosen for each. Empty otherwise.

paymentobjectThe payment choice, in the same shape.currentstringWhat the order uses now.

multiplebooleanAlways false: an order is paid one way.

optionsobject\[\]What it could move to.valuestringThe `plugin_id` pairing to send.

labelstringAs the merchant named it.

### Errors

CodeHTTPMeans

not\_found404No such order, or the operator may not see it.

```
curl "$SHOP/hikashop-api/v1/orders/{id}/methods" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"shipping"</span>: {
            <span class="k">"current"</span>: <span class="s">"manual_1"</span>,
            <span class="k">"multiple"</span>: <span class="n">false</span>,
            <span class="k">"options"</span>: [
                {
                    <span class="k">"value"</span>: <span class="s">"manual_1"</span>,
                    <span class="k">"label"</span>: <span class="s">"Vendor 2 only shipping"</span>
                },
                {
                    <span class="k">"value"</span>: <span class="s">"manual_6"</span>,
                    <span class="k">"label"</span>: <span class="s">"Test Flat Shipping"</span>
                },
                {
                    <span class="k">"value"</span>: <span class="s">"manual_3"</span>,
                    <span class="k">"label"</span>: <span class="s">"Express Test Flat Rate"</span>
                },
                {
                    <span class="k">"value"</span>: <span class="s">"fedextest_2-1"</span>,
                    <span class="k">"label"</span>: <span class="s">"FedEx TEST - FedEx Ground"</span>
                }
            ],
            <span class="k">"groups"</span>: []
        },
        <span class="k">"payment"</span>: {
            <span class="k">"current"</span>: <span class="s">"paypalcheckout_3"</span>,
            <span class="k">"multiple"</span>: <span class="n">false</span>,
            <span class="k">"options"</span>: [
                {
                    <span class="k">"value"</span>: <span class="s">"banktransfer_1"</span>,
                    <span class="k">"label"</span>: <span class="s">"Bank transfer"</span>
                },
                {
                    <span class="k">"value"</span>: <span class="s">"linepay_2"</span>,
                    <span class="k">"label"</span>: <span class="s">"LINE Pay"</span>
                },
                {
                    <span class="k">"value"</span>: <span class="s">"paypalcheckout_3"</span>,
                    <span class="k">"label"</span>: <span class="s">"PayPal Checkout Express Test"</span>
                }
            ]
        }
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Make an address the default

PUT /customers/**{id}**/addresses/**{aid}**/default write since 6.6.0

Marks one of a customer's addresses as their default, and answers with the customer as it now stands.

The default is per kind: an address used for billing becomes the default billing address, and the one it replaces stops being it. Nothing is sent in the body.

### Path

ParameterTypeDescription

idrequiredintegerThe customer.

aidrequiredintegerThe address, from &#96;addresses\[\].id&#96;.

### Response expand all

FieldTypeDescription

idintegerThe HikaShop customer id, which is what every customer route takes.

cms\_idintegerThe Joomla or WordPress user id, `0` for a guest with no account.

namestring

emailstring

usernamestringThe login, empty for a guest.

typestring`registered` or `guest`.

blockedbooleanWhether the CMS account is disabled.

can\_edit\_accountbooleanWhether this operator may change the login and password of this particular account. False for an account above their own level, which is how a super user is protected from staff.

groups\_editablebooleanWhether this operator may change which groups the customer is in.

groupsobject\[\]The groups they are in.idinteger

titlestring

available\_groupsobject\[\]Every group, with whether this operator may put the customer into it, so a picker can grey out the rest rather than offering a refusal.idinteger

titlestring

assignablebooleanFalse for a group this operator may not grant.

createdintegerUnix timestamp of the first time the shop saw them.

addressesobject\[\]Their addresses, defaults first.idinteger

typesstring\[\]Which of `billing` and `shipping` it is used for.

namestring

companystring

streetstring

citystring

post\_codestring

telephonestring

defaultbooleanWhether it is the default for one of its types.

formattedobjectThe address laid out the way this shop lays addresses out, which depends on its address format setting.textstringSeveral lines, for an invoice or a label.

one\_linestringOne line, for a list.

ordersobject\[\]Their orders, newest first, enough to list them.idinteger

numberstringThe number the customer sees.

statusstringA namekey.

createdintegerUnix timestamp.

totalnumberTax included, in the order currency.

currency\_idintegerThat currency.

fieldsobject\[\]The definitions of your own customer fields.

custom\_fieldsobjectTheir values, keyed by namekey. The keys depend on the shop; `fields` says what they are.

custom\_field\_filesobjectFor a field holding a file, the file behind the value. Keyed the same way.

### Errors

CodeHTTPMeans

not\_found404No such customer or address, or the operator may not change them.

```
curl -X PUT "$SHOP/hikashop-api/v1/customers/{id}/addresses/{id}/default" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">20</span>,
        <span class="k">"cms_id"</span>: <span class="n">0</span>,
        <span class="k">"name"</span>: <span class="s">"John Doe"</span>,
        <span class="k">"email"</span>: <span class="s">"<joomla-hidden-mail base="" first="YnV5ZXI=" is-email="1" is-link="1" last="ZXhhbXBsZS50ZXN0" text="YnV5ZXJAZXhhbXBsZS50ZXN0">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>"</span>,
        <span class="k">"username"</span>: <span class="s">""</span>,
        <span class="k">"type"</span>: <span class="s">"guest"</span>,
        <span class="k">"blocked"</span>: <span class="n">false</span>,
        <span class="k">"can_edit_account"</span>: <span class="n">true</span>,
        <span class="k">"groups_editable"</span>: <span class="n">false</span>,
        <span class="k">"groups"</span>: [],
        <span class="k">"available_groups"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">1</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">9</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">6</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">7</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            "… 5 more, trimmed for the example"
        ],
        <span class="k">"created"</span>: <span class="n">1786963440</span>,
        <span class="k">"addresses"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">26</span>,
                <span class="k">"types"</span>: [
                    "billing"
                ],
                <span class="k">"name"</span>: <span class="s">"John Doe"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">true</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            {
                <span class="k">"id"</span>: <span class="n">25</span>,
                <span class="k">"types"</span>: [
                    "shipping"
                ],
                <span class="k">"name"</span>: <span class="s">"John Doe"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">true</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            }
        ],
        <span class="k">"orders"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">26</span>,
                <span class="k">"number"</span>: <span class="s">"B2D6"</span>,
                <span class="k">"status"</span>: <span class="s">"created"</span>,
                <span class="k">"created"</span>: <span class="n">1785338765</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">28</span>,
                <span class="k">"number"</span>: <span class="s">"B2F8"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1785321840</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">30</span>,
                <span class="k">"number"</span>: <span class="s">"ZBUNDLE"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1784803440</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">22</span>,
                <span class="k">"number"</span>: <span class="s">"Z22"</span>,
                <span class="k">"status"</span>: <span class="s">"created"</span>,
                <span class="k">"created"</span>: <span class="n">1783721823</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            }
        ],
        <span class="k">"fields"</span>: [],
        <span class="k">"custom_fields"</span>: [],
        <span class="k">"custom_field_files"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Create a characteristic or one of its values

POST /products/characteristics write since 6.6.0

Creates a characteristic, such as Size, or a value of one, such as XL.

Send a `name` for a characteristic, or a `value` with the `parent_id` of the characteristic it belongs to. They are the same records at two levels, which is why one route serves both.

### Body

FieldTypeDescription

namestringThe name of a new characteristic. Give this or `value`.

valuestringThe name of a new value, with `parent_id`.

parent\_idintegerThe characteristic a value belongs to.

### Response expand all

FieldTypeDescription

idintegerWhat was created, which is what a variant refers to.

valuestringIts name.

parent\_idinteger`0` for a characteristic, the characteristic for a value.

### Errors

CodeHTTPMeans

invalid\_request400Neither a name nor a value was given.

save\_failed500The shop refused to save it.

```
curl -X POST "$SHOP/hikashop-api/v1/products/characteristics" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Documentation capture"
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">904</span>,
        <span class="k">"value"</span>: <span class="s">"Documentation capture"</span>,
        <span class="k">"parent_id"</span>: <span class="n">0</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Create a product category

POST /products/categories write since 6.6.0

Creates a category under another, or at the top of the product tree when no parent is given.

### Body

FieldTypeDescription

namerequiredstringIts name.

parent\_idintegerThe category to put it under. Omit for the top of the tree.

publishedbooleanDefaults to published.

descriptionstringThe long description, as HTML.

meta\_descriptionstringSEO description.

accessobjectWho may see it.

custom\_fieldsobjectYour own category fields, keyed by namekey.

### Response expand all

FieldTypeDescription

idintegerThe category that was created.

namestring

parent\_idintegerWhere it sits.

publishedboolean

### Errors

CodeHTTPMeans

invalid\_fields400One of your own fields was rejected by its own rules.

save\_failed500The shop refused to save it.

```
curl -X POST "$SHOP/hikashop-api/v1/products/categories" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Documentation capture"
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">288</span>,
        <span class="k">"name"</span>: <span class="s">"Documentation capture"</span>,
        <span class="k">"parent_id"</span>: <span class="n">2</span>,
        <span class="k">"published"</span>: <span class="n">true</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Create a manufacturer

POST /products/manufacturers write since 6.6.0

Creates a brand. HikaShop keeps manufacturers in the category tree under their own root, so this takes the same fields as a category and answers the same way.

### Body

FieldTypeDescription

namerequiredstringThe brand name.

parent\_idintegerA manufacturer to nest it under, which most shops do not use.

publishedbooleanDefaults to published.

descriptionstringThe long description, as HTML.

meta\_descriptionstringSEO description.

accessobjectWho may see it.

custom\_fieldsobjectYour own category fields.

### Response expand all

FieldTypeDescription

idintegerThe manufacturer that was created, which is what `manufacturer_id` on a product stores.

namestring

parent\_idintegerIts root.

publishedboolean

### Errors

CodeHTTPMeans

invalid\_fields400One of your own fields was rejected by its own rules.

save\_failed500The shop refused to save it.

```
curl -X POST "$SHOP/hikashop-api/v1/products/manufacturers" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Documentation capture brand"
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">289</span>,
        <span class="k">"name"</span>: <span class="s">"Documentation capture brand"</span>,
        <span class="k">"parent_id"</span>: <span class="n">10</span>,
        <span class="k">"published"</span>: <span class="n">true</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Update a category

PUT /categories/**{id}** write since 6.6.0

Changes the fields you send and leaves the rest alone. It serves manufacturers and the other trees as well, since they are all categories.

### Path

ParameterTypeDescription

idrequiredintegerThe category.

### Body

Any of `name`, `parent_id`, `published`, `description`, `meta_description`, `access` and `custom_fields`. What you do not send keeps its value.

### Response expand all

FieldTypeDescription

idstring

fieldsobject\[\]The definitions of your own category fields.namekeystringThe key its value is stored under.

labelstringTranslated into the operator's language.

typestringWhat to render: `text`, `radio`, `singledropdown`, `file`, and the rest.

raw\_typestringHikaShop's own name for the type.

requiredbooleanWhether the shop refuses to save without it.

defaultstringThe value used when none is given.

optionsobject\[\]The choices, for a field that has them.valuestringWhat to send back when this choice is picked.

labelstringWhat to show.

label\_keystringThe translation key behind the label, when there is one.

multiplebooleanWhether more than one may be chosen.

translatablebooleanWhether its value can be translated.

upload\_dirstringFor a file field, where its uploads are kept.

allowed\_extensionsstringFor a file field, the extensions it accepts. Empty means the shop default.

date\_formatstringFor a date field, the format it is stored in.

namestring

parent\_idintegerIts parent.

typestringWhich tree it belongs to: `product`, `manufacturer`, `tax`, and so on.

descriptionstringThe long description, as HTML.

meta\_descriptionstringSEO description.

publishedboolean

accessobjectWho may see it.modestring`all`, `none`, or `groups` when it is restricted to some.

groupsinteger\[\]User \*\*group\*\* ids, and not Joomla view levels. The two id spaces overlap and disagree, so a value that looks plausible can grant the wrong audience.

imagestring\|nullAbsolute URL of its image, `null` when it has none.

custom\_fieldsobjectTheir values, keyed by namekey. The keys depend on the shop; `fields` says what they are.

custom\_field\_filesobjectFor a field holding a file, the file behind the value. Keyed the same way.

### Errors

CodeHTTPMeans

not\_found404No such category, or the operator may not change it.

invalid\_fields400One of your own fields was rejected by its own rules.

```
curl -X PUT "$SHOP/hikashop-api/v1/categories/{id}" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Shampoo"
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"fields"</span>: [],
        <span class="k">"id"</span>: <span class="n">252</span>,
        <span class="k">"name"</span>: <span class="s">"Shampoo"</span>,
        <span class="k">"parent_id"</span>: <span class="n">220</span>,
        <span class="k">"type"</span>: <span class="s">"product"</span>,
        <span class="k">"description"</span>: <span class="s">""</span>,
        <span class="k">"meta_description"</span>: <span class="s">""</span>,
        <span class="k">"published"</span>: <span class="n">true</span>,
        <span class="k">"access"</span>: {
            <span class="k">"mode"</span>: <span class="s">"all"</span>,
            <span class="k">"groups"</span>: []
        },
        <span class="k">"image"</span>: <span class="s">"http://localhost:<span class="n">8080</span>/joomla6_ext/images/com_hikashop/upload/demo-cat-252.png"</span>,
        <span class="k">"custom_fields"</span>: [],
        <span class="k">"custom_field_files"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Delete a category

DELETE /categories/**{id}** write since 6.6.0

Deletes a category. The products in it are not deleted; they simply stop being in it, and a product left in no category at all disappears from the shop's listings.

### Path

ParameterTypeDescription

idrequiredintegerThe category.

### Response expand all

FieldTypeDescription

idintegerThe category that was deleted.

deletedbooleanTrue when the row is gone.

### Errors

CodeHTTPMeans

not\_found404No such category, or the operator may not delete it.

```
curl -X DELETE "$SHOP/hikashop-api/v1/categories/{id}" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">287</span>,
        <span class="k">"deleted"</span>: <span class="n">true</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## List the entries of the HikaShop log

GET /logs read since 6.8.0

The log of System &gt; Logs, newest first: what payment and shipping methods write when their Debug option is on, and the errors HikaShop meets. The data of an entry is left out; `data_size` says how much there is, and `GET /logs/{id}` returns it.

Read a payment problem by finding one entry about the order (`order_id`), then listing its `request`: that gives every line the notification wrote, in order.

### Query

ParameterTypeDescription

startintegerOffset. Defaults to `0`.

limitintegerDefaults to `50`, capped at `200`.

sourcestringOnly this source.

typestring`payment`, `shipping`, `plugin` or `core`.

levelstringThis level and the worse ones: `debug`, `info`, `warning` or `error`.

order\_idintegerOnly the entries about this order.

requeststringOnly the entries one request wrote.

sincestringFrom this date: a Unix timestamp, or a date such as `2026-10-01`.

untilstringUp to this date; a bare day such as `2026-10-01` is included.

searchstringText in the message, the data, the source, the address or the IP.

### Response a list expand all

FieldTypeDescription

order\_idintegerThe order it is about, `0` when none. A payment plugin records the order it loaded.

idinteger

createdintegerUnix timestamp of when it was written.

levelstring`debug`, `info`, `warning` or `error`.

sourcestringWhat wrote it: a plugin name such as `paypal`, or a part of HikaShop such as `mail`.

typestring`payment`, `shipping`, `plugin` or `core`.

messagestringThe text of the entry, or the beginning of its data when it only had data.

user\_idintegerThe user logged in when it was written, `0` for a guest or a call from a server.

ipstringIP address of the request. A payment notification comes from the provider's servers.

urlstringAddress of the request, with secrets in its query masked.

requeststringId shared by every entry one request wrote; filter on it to read a notification from start to end.

data\_sizeintegerBytes of data the entry holds beyond its message, `0` when none.

### Envelope meta

FieldTypeDescription

startintegerEchoes the offset used.

limitintegerEchoes the page size used.

totalintegerEntries matching the filters, before paging.

```
curl "$SHOP/hikashop-api/v1/logs?limit=2" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: [
        {
            <span class="k">"id"</span>: <span class="n">4</span>,
            <span class="k">"created"</span>: <span class="n">1792671482</span>,
            <span class="k">"level"</span>: <span class="s">"debug"</span>,
            <span class="k">"source"</span>: <span class="s">"ups2"</span>,
            <span class="k">"type"</span>: <span class="s">"shipping"</span>,
            <span class="k">"message"</span>: <span class="s">"Rate request"</span>,
            <span class="k">"order_id"</span>: <span class="n">0</span>,
            <span class="k">"user_id"</span>: <span class="n">0</span>,
            <span class="k">"ip"</span>: <span class="s">"203.0.113.7"</span>,
            <span class="k">"url"</span>: <span class="s">"cli: seed.php"</span>,
            <span class="k">"request"</span>: <span class="s">"6356ff9319045d36"</span>,
            <span class="k">"data_size"</span>: <span class="n">16</span>
        },
        {
            <span class="k">"id"</span>: <span class="n">2</span>,
            <span class="k">"created"</span>: <span class="n">1792671482</span>,
            <span class="k">"level"</span>: <span class="s">"info"</span>,
            <span class="k">"source"</span>: <span class="s">"paypal"</span>,
            <span class="k">"type"</span>: <span class="s">"payment"</span>,
            <span class="k">"message"</span>: <span class="s">"Notification refused: bad signature"</span>,
            <span class="k">"order_id"</span>: <span class="n">1</span>,
            <span class="k">"user_id"</span>: <span class="n">0</span>,
            <span class="k">"ip"</span>: <span class="s">"203.0.113.7"</span>,
            <span class="k">"url"</span>: <span class="s">"cli: seed.php"</span>,
            <span class="k">"request"</span>: <span class="s">"6356ff9319045d36"</span>,
            <span class="k">"data_size"</span>: <span class="n">0</span>
        }
    ],
    <span class="k">"meta"</span>: {
        <span class="k">"start"</span>: <span class="n">0</span>,
        <span class="k">"limit"</span>: <span class="n">2</span>,
        <span class="k">"total"</span>: <span class="n">3</span>
    },
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Read one entry of the HikaShop log with its data

GET /logs/**{id}** read since 6.8.0

One entry with everything it holds. Card numbers and security codes, passwords, keys and tokens were masked when it was written; a gateway's own field names can still slip through, so read the data before passing it on.

### Path

ParameterTypeDescription

idrequiredintegerThe log entry.

### Response expand all

FieldTypeDescription

idinteger

createdintegerUnix timestamp of when it was written.

levelstring`debug`, `info`, `warning` or `error`.

sourcestringWhat wrote it: a plugin name such as `paypal`, or a part of HikaShop such as `mail`.

typestring`payment`, `shipping`, `plugin` or `core`.

messagestringThe text of the entry, or the beginning of its data when it only had data.

order\_idintegerThe order it is about, `0` when none. A payment plugin records the order it loaded.

user\_idintegerThe user logged in when it was written, `0` for a guest or a call from a server.

ipstringIP address of the request. A payment notification comes from the provider's servers.

urlstringAddress of the request, with secrets in its query masked.

requeststringId shared by every entry one request wrote; filter on it to read a notification from start to end.

data\_sizeintegerBytes of data the entry holds beyond its message, `0` when none.

dataobject\|array\|stringWhat the entry holds beyond its message: the decoded JSON when it was an array or an object, the text otherwise, an empty string when none.

### Errors

CodeHTTPMeans

not\_found404No such entry.

```
curl "$SHOP/hikashop-api/v1/logs/4" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">4</span>,
        <span class="k">"created"</span>: <span class="n">1792671482</span>,
        <span class="k">"level"</span>: <span class="s">"debug"</span>,
        <span class="k">"source"</span>: <span class="s">"ups2"</span>,
        <span class="k">"type"</span>: <span class="s">"shipping"</span>,
        <span class="k">"message"</span>: <span class="s">"Rate request"</span>,
        <span class="k">"order_id"</span>: <span class="n">0</span>,
        <span class="k">"user_id"</span>: <span class="n">0</span>,
        <span class="k">"ip"</span>: <span class="s">"203.0.113.7"</span>,
        <span class="k">"url"</span>: <span class="s">"cli: seed.php"</span>,
        <span class="k">"request"</span>: <span class="s">"6356ff9319045d36"</span>,
        <span class="k">"data_size"</span>: <span class="n">16</span>,
        <span class="k">"data"</span>: <span class="s">"<xml>rates</xml>"</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Read one discount or coupon

GET /discounts/**{id}** read since 6.6.0

One reduction with every restriction it carries.

### Path

ParameterTypeDescription

idrequiredintegerThe discount or coupon.

### Response expand all

FieldTypeDescription

idinteger

typestring`discount` applies by itself, `coupon` waits for its code.

codestringWhat the customer types. Empty on a discount.

kindstringWhether the value is a percentage or a fixed amount.

valuenumberThe reduction, read according to `kind`.

currency\_idintegerThe currency a fixed amount is in.

publishedboolean

startinteger\|nullUnix timestamp before which it does not apply.

endinteger\|nullUnix timestamp after which it expires.

minimum\_ordernumberOrder total below which it does not apply, `0` for none.

maximum\_ordernumberOrder total above which it stops applying, `0` for none.

quotaintegerHow many times it may be used in total, `0` for no limit.

quota\_per\_userintegerHow many times one customer may use it, `0` for no limit.

used\_timesintegerHow many times it already has been.

tax\_includedbooleanWhether the value is understood as tax included.

tax\_idintegerThe tax category of the reduction itself.

shipping\_percentnumberA reduction on the shipping rather than on the goods.

minimum\_productsintegerFewest items in the cart for it to apply.

maximum\_productsintegerMost items for it to still apply.

product\_idsinteger\[\]Restricted to these products. Empty means all of them.

exclude\_product\_idsinteger\[\]Never applies to these.

category\_idsinteger\[\]Restricted to these categories.

category\_childsbooleanWhether those categories include their sub-categories.

exclude\_category\_idsinteger\[\]Never applies in these categories.

exclude\_category\_childsbooleanWhether those exclusions include sub-categories.

zone\_idsinteger\[\]Restricted to these zones.

user\_idsinteger\[\]Restricted to these customers.

accessobjectWhich user groups it is for, in the usual `mode` and `groups` shape.modestring`all`, `none`, or `groups` when it is restricted to some.

groupsinteger\[\]User \*\*group\*\* ids, and not Joomla view levels. The two id spaces overlap and disagree, so a value that looks plausible can grant the wrong audience.

exclude\_accessobjectWhich user groups it is never for.modestring`all`, `none`, or `groups` when it is restricted to some.

groupsinteger\[\]User \*\*group\*\* ids, and not Joomla view levels. The two id spaces overlap and disagree, so a value that looks plausible can grant the wrong audience.

auto\_loadbooleanFor a coupon, whether the shop applies it without the customer typing it.

product\_onlybooleanWhether it reduces only the goods and leaves the fees alone.

discounted\_productsintegerHow many products in the cart it applied to, on a discount that has been used.

### Errors

CodeHTTPMeans

not\_found404No such discount, or the operator may not see it.

```
curl "$SHOP/hikashop-api/v1/discounts/1" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">1</span>,
        <span class="k">"type"</span>: <span class="s">"coupon"</span>,
        <span class="k">"code"</span>: <span class="s">"APPTEST10"</span>,
        <span class="k">"kind"</span>: <span class="s">"flat"</span>,
        <span class="k">"value"</span>: <span class="n">10</span>,
        <span class="k">"currency_id"</span>: <span class="n">1</span>,
        <span class="k">"published"</span>: <span class="n">true</span>,
        <span class="k">"start"</span>: <span class="n">0</span>,
        <span class="k">"end"</span>: <span class="n">0</span>,
        <span class="k">"minimum_order"</span>: <span class="n">0</span>,
        <span class="k">"maximum_order"</span>: <span class="n">0</span>,
        <span class="k">"quota"</span>: <span class="n">0</span>,
        <span class="k">"quota_per_user"</span>: <span class="n">0</span>,
        <span class="k">"used_times"</span>: <span class="n">0</span>,
        <span class="k">"tax_included"</span>: <span class="n">false</span>,
        <span class="k">"tax_id"</span>: <span class="n">0</span>,
        <span class="k">"shipping_percent"</span>: <span class="n">0</span>,
        <span class="k">"minimum_products"</span>: <span class="n">0</span>,
        <span class="k">"maximum_products"</span>: <span class="n">0</span>,
        <span class="k">"product_ids"</span>: [],
        <span class="k">"exclude_product_ids"</span>: [],
        <span class="k">"category_ids"</span>: [],
        <span class="k">"category_childs"</span>: <span class="n">false</span>,
        <span class="k">"exclude_category_ids"</span>: [],
        <span class="k">"exclude_category_childs"</span>: <span class="n">false</span>,
        <span class="k">"zone_ids"</span>: [],
        <span class="k">"user_ids"</span>: [],
        <span class="k">"access"</span>: {
            <span class="k">"mode"</span>: <span class="s">"all"</span>,
            <span class="k">"groups"</span>: []
        },
        <span class="k">"exclude_access"</span>: {
            <span class="k">"mode"</span>: <span class="s">"none"</span>,
            <span class="k">"groups"</span>: []
        },
        <span class="k">"auto_load"</span>: <span class="n">false</span>,
        <span class="k">"product_only"</span>: <span class="n">false</span>,
        <span class="k">"discounted_products"</span>: <span class="n">0</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Create a discount or a coupon

POST /discounts write since 6.6.0

Creates a reduction and answers with it as the shop stored it.

`type` decides which kind it is: a `coupon` needs a `code`, a `discount` applies by itself. Either way `value` is required, read according to `kind`.

### Body

Any field of a discount. `type` and `value` are required, and a coupon also needs a `code`. The restriction lists take ids, and an empty list means no restriction of that kind.

### Response expand all

FieldTypeDescription

idinteger

typestring`discount` applies by itself, `coupon` waits for its code.

codestringWhat the customer types. Empty on a discount.

kindstringWhether the value is a percentage or a fixed amount.

valuenumberThe reduction, read according to `kind`.

currency\_idintegerThe currency a fixed amount is in.

publishedboolean

startinteger\|nullUnix timestamp before which it does not apply.

endinteger\|nullUnix timestamp after which it expires.

minimum\_ordernumberOrder total below which it does not apply, `0` for none.

maximum\_ordernumberOrder total above which it stops applying, `0` for none.

quotaintegerHow many times it may be used in total, `0` for no limit.

quota\_per\_userintegerHow many times one customer may use it, `0` for no limit.

used\_timesintegerHow many times it already has been.

tax\_includedbooleanWhether the value is understood as tax included.

tax\_idintegerThe tax category of the reduction itself.

shipping\_percentnumberA reduction on the shipping rather than on the goods.

minimum\_productsintegerFewest items in the cart for it to apply.

maximum\_productsintegerMost items for it to still apply.

product\_idsinteger\[\]Restricted to these products. Empty means all of them.

exclude\_product\_idsinteger\[\]Never applies to these.

category\_idsinteger\[\]Restricted to these categories.

category\_childsbooleanWhether those categories include their sub-categories.

exclude\_category\_idsinteger\[\]Never applies in these categories.

exclude\_category\_childsbooleanWhether those exclusions include sub-categories.

zone\_idsinteger\[\]Restricted to these zones.

user\_idsinteger\[\]Restricted to these customers.

accessobjectWhich user groups it is for, in the usual `mode` and `groups` shape.modestring`all`, `none`, or `groups` when it is restricted to some.

groupsinteger\[\]User \*\*group\*\* ids, and not Joomla view levels. The two id spaces overlap and disagree, so a value that looks plausible can grant the wrong audience.

exclude\_accessobjectWhich user groups it is never for.modestring`all`, `none`, or `groups` when it is restricted to some.

groupsinteger\[\]User \*\*group\*\* ids, and not Joomla view levels. The two id spaces overlap and disagree, so a value that looks plausible can grant the wrong audience.

auto\_loadbooleanFor a coupon, whether the shop applies it without the customer typing it.

product\_onlybooleanWhether it reduces only the goods and leaves the fees alone.

discounted\_productsintegerHow many products in the cart it applied to, on a discount that has been used.

### Errors

CodeHTTPMeans

code\_required400A coupon needs a code.

code\_taken400Another coupon already uses that code.

value\_required400A reduction needs a value.

not\_found404Not reachable when creating: the same handler serves the update, where it means no such discount.

save\_failed500The shop refused to save it.

```
curl -X POST "$SHOP/hikashop-api/v1/discounts" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "coupon",
    "code": "DOCCAPTURE",
    "kind": "percent",
    "value": 10
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">492</span>,
        <span class="k">"type"</span>: <span class="s">"coupon"</span>,
        <span class="k">"code"</span>: <span class="s">"DOCCAPTURE"</span>,
        <span class="k">"kind"</span>: <span class="s">"percent"</span>,
        <span class="k">"value"</span>: <span class="n">10</span>,
        <span class="k">"currency_id"</span>: <span class="n">0</span>,
        <span class="k">"published"</span>: <span class="n">true</span>,
        <span class="k">"start"</span>: <span class="n">0</span>,
        <span class="k">"end"</span>: <span class="n">0</span>,
        <span class="k">"minimum_order"</span>: <span class="n">0</span>,
        <span class="k">"maximum_order"</span>: <span class="n">0</span>,
        <span class="k">"quota"</span>: <span class="n">0</span>,
        <span class="k">"quota_per_user"</span>: <span class="n">0</span>,
        <span class="k">"used_times"</span>: <span class="n">0</span>,
        <span class="k">"tax_included"</span>: <span class="n">false</span>,
        <span class="k">"tax_id"</span>: <span class="n">0</span>,
        <span class="k">"shipping_percent"</span>: <span class="n">0</span>,
        <span class="k">"minimum_products"</span>: <span class="n">0</span>,
        <span class="k">"maximum_products"</span>: <span class="n">0</span>,
        <span class="k">"product_ids"</span>: [],
        <span class="k">"exclude_product_ids"</span>: [],
        <span class="k">"category_ids"</span>: [],
        <span class="k">"category_childs"</span>: <span class="n">false</span>,
        <span class="k">"exclude_category_ids"</span>: [],
        <span class="k">"exclude_category_childs"</span>: <span class="n">false</span>,
        <span class="k">"zone_ids"</span>: [],
        <span class="k">"user_ids"</span>: [],
        <span class="k">"access"</span>: {
            <span class="k">"mode"</span>: <span class="s">"all"</span>,
            <span class="k">"groups"</span>: []
        },
        <span class="k">"exclude_access"</span>: {
            <span class="k">"mode"</span>: <span class="s">"none"</span>,
            <span class="k">"groups"</span>: []
        },
        <span class="k">"auto_load"</span>: <span class="n">false</span>,
        <span class="k">"product_only"</span>: <span class="n">false</span>,
        <span class="k">"discounted_products"</span>: <span class="n">0</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Update a discount or a coupon

PUT /discounts/**{id}** write since 6.6.0

Changes the fields you send and leaves the rest alone, and answers with the reduction as it now stands.

### Path

ParameterTypeDescription

idrequiredintegerThe discount or coupon.

### Body

Any field of a discount. What you do not send keeps its value. A restriction list you do send replaces the one it had.

### Response expand all

FieldTypeDescription

idinteger

typestring`discount` applies by itself, `coupon` waits for its code.

codestringWhat the customer types. Empty on a discount.

kindstringWhether the value is a percentage or a fixed amount.

valuenumberThe reduction, read according to `kind`.

currency\_idintegerThe currency a fixed amount is in.

publishedboolean

startinteger\|nullUnix timestamp before which it does not apply.

endinteger\|nullUnix timestamp after which it expires.

minimum\_ordernumberOrder total below which it does not apply, `0` for none.

maximum\_ordernumberOrder total above which it stops applying, `0` for none.

quotaintegerHow many times it may be used in total, `0` for no limit.

quota\_per\_userintegerHow many times one customer may use it, `0` for no limit.

used\_timesintegerHow many times it already has been.

tax\_includedbooleanWhether the value is understood as tax included.

tax\_idintegerThe tax category of the reduction itself.

shipping\_percentnumberA reduction on the shipping rather than on the goods.

minimum\_productsintegerFewest items in the cart for it to apply.

maximum\_productsintegerMost items for it to still apply.

product\_idsinteger\[\]Restricted to these products. Empty means all of them.

exclude\_product\_idsinteger\[\]Never applies to these.

category\_idsinteger\[\]Restricted to these categories.

category\_childsbooleanWhether those categories include their sub-categories.

exclude\_category\_idsinteger\[\]Never applies in these categories.

exclude\_category\_childsbooleanWhether those exclusions include sub-categories.

zone\_idsinteger\[\]Restricted to these zones.

user\_idsinteger\[\]Restricted to these customers.

accessobjectWhich user groups it is for, in the usual `mode` and `groups` shape.modestring`all`, `none`, or `groups` when it is restricted to some.

groupsinteger\[\]User \*\*group\*\* ids, and not Joomla view levels. The two id spaces overlap and disagree, so a value that looks plausible can grant the wrong audience.

exclude\_accessobjectWhich user groups it is never for.modestring`all`, `none`, or `groups` when it is restricted to some.

groupsinteger\[\]User \*\*group\*\* ids, and not Joomla view levels. The two id spaces overlap and disagree, so a value that looks plausible can grant the wrong audience.

auto\_loadbooleanFor a coupon, whether the shop applies it without the customer typing it.

product\_onlybooleanWhether it reduces only the goods and leaves the fees alone.

discounted\_productsintegerHow many products in the cart it applied to, on a discount that has been used.

### Errors

CodeHTTPMeans

not\_found404No such discount, or the operator may not change it.

code\_required400A coupon needs a code, so it cannot be cleared on one.

code\_taken400Another coupon already uses that code.

value\_required400A reduction needs a value.

save\_failed500The shop refused to save it.

```
curl -X PUT "$SHOP/hikashop-api/v1/discounts/1" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "flat",
    "value": 10
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">1</span>,
        <span class="k">"type"</span>: <span class="s">"coupon"</span>,
        <span class="k">"code"</span>: <span class="s">"APPTEST10"</span>,
        <span class="k">"kind"</span>: <span class="s">"flat"</span>,
        <span class="k">"value"</span>: <span class="n">10</span>,
        <span class="k">"currency_id"</span>: <span class="n">1</span>,
        <span class="k">"published"</span>: <span class="n">true</span>,
        <span class="k">"start"</span>: <span class="n">0</span>,
        <span class="k">"end"</span>: <span class="n">0</span>,
        <span class="k">"minimum_order"</span>: <span class="n">0</span>,
        <span class="k">"maximum_order"</span>: <span class="n">0</span>,
        <span class="k">"quota"</span>: <span class="n">0</span>,
        <span class="k">"quota_per_user"</span>: <span class="n">0</span>,
        <span class="k">"used_times"</span>: <span class="n">0</span>,
        <span class="k">"tax_included"</span>: <span class="n">false</span>,
        <span class="k">"tax_id"</span>: <span class="n">0</span>,
        <span class="k">"shipping_percent"</span>: <span class="n">0</span>,
        <span class="k">"minimum_products"</span>: <span class="n">0</span>,
        <span class="k">"maximum_products"</span>: <span class="n">0</span>,
        <span class="k">"product_ids"</span>: [],
        <span class="k">"exclude_product_ids"</span>: [],
        <span class="k">"category_ids"</span>: [],
        <span class="k">"category_childs"</span>: <span class="n">false</span>,
        <span class="k">"exclude_category_ids"</span>: [],
        <span class="k">"exclude_category_childs"</span>: <span class="n">false</span>,
        <span class="k">"zone_ids"</span>: [],
        <span class="k">"user_ids"</span>: [],
        <span class="k">"access"</span>: {
            <span class="k">"mode"</span>: <span class="s">"all"</span>,
            <span class="k">"groups"</span>: []
        },
        <span class="k">"exclude_access"</span>: {
            <span class="k">"mode"</span>: <span class="s">"none"</span>,
            <span class="k">"groups"</span>: []
        },
        <span class="k">"auto_load"</span>: <span class="n">false</span>,
        <span class="k">"product_only"</span>: <span class="n">false</span>,
        <span class="k">"discounted_products"</span>: <span class="n">0</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Delete a discount or a coupon

DELETE /discounts/**{id}** write since 6.6.0

Deletes a reduction. Orders that already used it keep the amount they were given: the discount on an order is a figure, not a pointer at this row.

### Path

ParameterTypeDescription

idrequiredintegerThe discount or coupon.

### Response expand all

FieldTypeDescription

deletedbooleanTrue when the row is gone.

### Errors

CodeHTTPMeans

not\_found404No such discount, or the operator may not delete it.

```
curl -X DELETE "$SHOP/hikashop-api/v1/discounts/{id}" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"deleted"</span>: <span class="n">493</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Create a customer

POST /customers write since 6.6.0

Creates a customer from an email address and a name, as a guest: no account, no password, nothing for them to log in with.

`POST /customers/{id}/account` turns one into a registered customer afterwards.

### Body

FieldTypeDescription

emailrequiredstringMust not belong to another customer.

namestringTheir display name.

### Response expand all

FieldTypeDescription

idintegerThe customer that was created.

### Errors

CodeHTTPMeans

email\_taken400Another customer already has that address.

save\_failed500The shop refused to save it.

```
curl -X POST "$SHOP/hikashop-api/v1/customers" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "<joomla-hidden-mail base="" first="YnV5ZXI=" is-email="1" is-link="1" last="ZXhhbXBsZS50ZXN0" text="YnV5ZXJAZXhhbXBsZS50ZXN0">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>",
    "name": "Alex Marchand"
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">5428</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Attach a downloadable file

POST /products/**{id}**/files write since 6.6.0

The same as attaching an image, for the files a customer downloads after buying. `free_download` decides whether they have to buy it first.

### Path

ParameterTypeDescription

idrequiredintegerThe product.

### Body

FieldTypeDescription

datastringThe bytes, base64 encoded. Give this or `path`.

pathstringA file already in the upload folder.

namestringThe file name to store it under.

descriptionstringA note on the file.

accessobjectWho may download it.

### Response expand all

FieldTypeDescription

idinteger

namestring

pathstringRelative to the upload folder.

urlstringAbsolute, ready to display.

orderingintegerWhere it sits among the others; the first image is the one the shop shows.

descriptionstringThe alt text for an image, or a note on a file.

accessobjectWho may see or download it.modestring`all`, `none`, or `groups` when it is restricted to some.

groupsinteger\[\]User \*\*group\*\* ids, and not Joomla view levels. The two id spaces overlap and disagree, so a value that looks plausible can grant the wrong audience.

free\_downloadbooleanFiles only: whether it can be downloaded without buying the product.

### Errors

CodeHTTPMeans

not\_found404No such product, or the operator may not change it.

bad\_type400The extension is not one this shop accepts.

write\_failed500The upload folder refused the file.

```
curl -X POST "$SHOP/hikashop-api/v1/products/{id}/files" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "data": "JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0ZpbHRlci9GbGF0ZURlY29kZT4+CnN0cmVhbQp4nD3HsQ2AMAxE0T5TXA9IjhOSeAAkKmpLLIAoEAWK2F9wQKK5e/qXcMYKUdE4RSxHTXjuvet3D1CNPqBQZmxbKimw5jJUOJyzcSSJifKPZJa5ffwAAP//AwBQSwMEFAAGAAgAAAAhAA==",
    "name": "documentation-capture.pdf",
    "description": "A small file"
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">8338</span>,
        <span class="k">"name"</span>: <span class="s">"documentation-capture.pdf"</span>,
        <span class="k">"path"</span>: <span class="s">"documentation-capture_2.pdf"</span>,
        <span class="k">"url"</span>: <span class="s">""</span>,
        <span class="k">"ordering"</span>: <span class="n">1</span>,
        <span class="k">"description"</span>: <span class="s">"A small file"</span>,
        <span class="k">"access"</span>: {
            <span class="k">"mode"</span>: <span class="s">"all"</span>,
            <span class="k">"groups"</span>: []
        },
        <span class="k">"free_download"</span>: <span class="n">false</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## A blank address form

GET /customers/**{id}**/addresses read since 6.6.0

The address form of a customer: the shop's own address fields, and the values of the address asked for. Without an address id it is a blank form, which is what you draw to add one.

The form comes with the values because a shop decides its own address fields, so build from `fields` rather than assuming a shape.

### Path

ParameterTypeDescription

idrequiredintegerThe customer.

### Response expand all

FieldTypeDescription

address\_idintegerThe address this form is for, `0` for a new one.

typesstring\[\]Which of `billing` and `shipping` it is used for.

defaultstring\|nullWhich kind it is the default for, `null` when it is not a default.

fieldsobject\[\]The shop's address fields, in display order.namekeystringThe key its value is stored under.

typestringWhat to render: `text`, `radio`, `singledropdown`, `file`, and the rest.

raw\_typestringHikaShop's own name for the type.

labelstringTranslated into the operator's language.

defaultstringThe value used when none is given.

requiredbooleanWhether the shop refuses to save without it.

optionsobject\[\]The choices, for a field that has them.valuestringWhat to send back when this choice is picked.

labelstringWhat to show.

label\_keystringThe translation key behind the label, when there is one.

multiplebooleanWhether more than one may be chosen.

translatablebooleanWhether its value can be translated.

upload\_dirstringFor a file field, where its uploads are kept.

allowed\_extensionsstringFor a file field, the extensions it accepts. Empty means the shop default.

date\_formatstringFor a date field, the format it is stored in.

valuesobjectThe current values, keyed by field namekey. Empty on a blank form. Keyed by whatever address fields this shop has.

country\_namestringThe country spelled out, since the value is a zone namekey.

state\_namestringThe state spelled out, empty where the country has none.

### Errors

CodeHTTPMeans

not\_found404No such customer or address, or the operator may not see them.

```
curl "$SHOP/hikashop-api/v1/customers/{id}/addresses" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"address_id"</span>: <span class="n">0</span>,
        <span class="k">"types"</span>: [
            "billing"
        ],
        <span class="k">"default"</span>: <span class="n">false</span>,
        <span class="k">"fields"</span>: [
            {
                <span class="k">"namekey"</span>: <span class="s">"address_title"</span>,
                <span class="k">"type"</span>: <span class="s">"singledropdown"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"singledropdown"</span>,
                <span class="k">"label"</span>: <span class="s">"Title"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">true</span>,
                <span class="k">"options"</span>: [
                    {
                        <span class="k">"value"</span>: <span class="s">"Mr"</span>,
                        <span class="k">"label"</span>: <span class="s">"Mr"</span>,
                        <span class="k">"label_key"</span>: <span class="s">"HIKA_TITLE_MR"</span>
                    },
                    {
                        <span class="k">"value"</span>: <span class="s">"Mrs"</span>,
                        <span class="k">"label"</span>: <span class="s">"Mrs"</span>,
                        <span class="k">"label_key"</span>: <span class="s">"HIKA_TITLE_MRS"</span>
                    },
                    {
                        <span class="k">"value"</span>: <span class="s">"Miss"</span>,
                        <span class="k">"label"</span>: <span class="s">"Miss"</span>,
                        <span class="k">"label_key"</span>: <span class="s">"HIKA_TITLE_MISS"</span>
                    },
                    {
                        <span class="k">"value"</span>: <span class="s">"Ms"</span>,
                        <span class="k">"label"</span>: <span class="s">"Ms"</span>,
                        <span class="k">"label_key"</span>: <span class="s">"HIKA_TITLE_MS"</span>
                    },
                    "… 1 more, trimmed for the example"
                ],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            },
            {
                <span class="k">"namekey"</span>: <span class="s">"address_firstname"</span>,
                <span class="k">"type"</span>: <span class="s">"text"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"text"</span>,
                <span class="k">"label"</span>: <span class="s">"First name"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">true</span>,
                <span class="k">"options"</span>: [],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            },
            {
                <span class="k">"namekey"</span>: <span class="s">"address_lastname"</span>,
                <span class="k">"type"</span>: <span class="s">"text"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"text"</span>,
                <span class="k">"label"</span>: <span class="s">"Last name"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">true</span>,
                <span class="k">"options"</span>: [],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            },
            {
                <span class="k">"namekey"</span>: <span class="s">"address_company"</span>,
                <span class="k">"type"</span>: <span class="s">"text"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"text"</span>,
                <span class="k">"label"</span>: <span class="s">"Company"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">false</span>,
                <span class="k">"options"</span>: [],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            },
            "… 7 more, trimmed for the example"
        ],
        <span class="k">"values"</span>: {
            <span class="k">"address_title"</span>: <span class="s">"Mr"</span>,
            <span class="k">"address_firstname"</span>: <span class="s">"Alex"</span>,
            <span class="k">"address_lastname"</span>: <span class="s">"Marchand"</span>,
            <span class="k">"address_company"</span>: <span class="s">"Lilas SARL"</span>,
            <span class="k">"address_street"</span>: <span class="s">"12 rue des Lilas"</span>,
            <span class="k">"address_post_code"</span>: <span class="s">"44000"</span>,
            <span class="k">"address_city"</span>: <span class="s">"Nantes"</span>,
            <span class="k">"address_telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
            <span class="k">"address_country"</span>: <span class="s">""</span>,
            <span class="k">"address_state"</span>: <span class="s">""</span>,
            <span class="k">"address_vat"</span>: <span class="s">"FR00000000000"</span>
        },
        <span class="k">"country_name"</span>: <span class="s">""</span>,
        <span class="k">"state_name"</span>: <span class="s">""</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## An address with its form

GET /customers/**{customerId}**/addresses/**{addressId}** read since 6.6.0

The address form of a customer: the shop's own address fields, and the values of the address asked for. Without an address id it is a blank form, which is what you draw to add one.

The form comes with the values because a shop decides its own address fields, so build from `fields` rather than assuming a shape.

### Path

ParameterTypeDescription

customerIdrequiredintegerThe customer.

addressIdrequiredintegerThe address.

### Response expand all

FieldTypeDescription

address\_idintegerThe address this form is for, `0` for a new one.

typesstring\[\]Which of `billing` and `shipping` it is used for.

defaultstring\|nullWhich kind it is the default for, `null` when it is not a default.

fieldsobject\[\]The shop's address fields, in display order.namekeystringThe key its value is stored under.

typestringWhat to render: `text`, `radio`, `singledropdown`, `file`, and the rest.

raw\_typestringHikaShop's own name for the type.

labelstringTranslated into the operator's language.

defaultstringThe value used when none is given.

requiredbooleanWhether the shop refuses to save without it.

optionsobject\[\]The choices, for a field that has them.valuestringWhat to send back when this choice is picked.

labelstringWhat to show.

label\_keystringThe translation key behind the label, when there is one.

multiplebooleanWhether more than one may be chosen.

translatablebooleanWhether its value can be translated.

upload\_dirstringFor a file field, where its uploads are kept.

allowed\_extensionsstringFor a file field, the extensions it accepts. Empty means the shop default.

date\_formatstringFor a date field, the format it is stored in.

valuesobjectThe current values, keyed by field namekey. Empty on a blank form. Keyed by whatever address fields this shop has.

country\_namestringThe country spelled out, since the value is a zone namekey.

state\_namestringThe state spelled out, empty where the country has none.

### Errors

CodeHTTPMeans

not\_found404No such customer or address, or the operator may not see them.

```
curl "$SHOP/hikashop-api/v1/customers/{id}/addresses/{id}" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"address_id"</span>: <span class="n">23</span>,
        <span class="k">"types"</span>: [
            "shipping"
        ],
        <span class="k">"default"</span>: <span class="n">false</span>,
        <span class="k">"fields"</span>: [
            {
                <span class="k">"namekey"</span>: <span class="s">"address_title"</span>,
                <span class="k">"type"</span>: <span class="s">"singledropdown"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"singledropdown"</span>,
                <span class="k">"label"</span>: <span class="s">"Title"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">true</span>,
                <span class="k">"options"</span>: [
                    {
                        <span class="k">"value"</span>: <span class="s">"Mr"</span>,
                        <span class="k">"label"</span>: <span class="s">"Mr"</span>,
                        <span class="k">"label_key"</span>: <span class="s">"HIKA_TITLE_MR"</span>
                    },
                    {
                        <span class="k">"value"</span>: <span class="s">"Mrs"</span>,
                        <span class="k">"label"</span>: <span class="s">"Mrs"</span>,
                        <span class="k">"label_key"</span>: <span class="s">"HIKA_TITLE_MRS"</span>
                    },
                    {
                        <span class="k">"value"</span>: <span class="s">"Miss"</span>,
                        <span class="k">"label"</span>: <span class="s">"Miss"</span>,
                        <span class="k">"label_key"</span>: <span class="s">"HIKA_TITLE_MISS"</span>
                    },
                    {
                        <span class="k">"value"</span>: <span class="s">"Ms"</span>,
                        <span class="k">"label"</span>: <span class="s">"Ms"</span>,
                        <span class="k">"label_key"</span>: <span class="s">"HIKA_TITLE_MS"</span>
                    },
                    "… 1 more, trimmed for the example"
                ],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            },
            {
                <span class="k">"namekey"</span>: <span class="s">"address_firstname"</span>,
                <span class="k">"type"</span>: <span class="s">"text"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"text"</span>,
                <span class="k">"label"</span>: <span class="s">"First name"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">true</span>,
                <span class="k">"options"</span>: [],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            },
            {
                <span class="k">"namekey"</span>: <span class="s">"address_lastname"</span>,
                <span class="k">"type"</span>: <span class="s">"text"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"text"</span>,
                <span class="k">"label"</span>: <span class="s">"Last name"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">true</span>,
                <span class="k">"options"</span>: [],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            },
            {
                <span class="k">"namekey"</span>: <span class="s">"address_company"</span>,
                <span class="k">"type"</span>: <span class="s">"text"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"text"</span>,
                <span class="k">"label"</span>: <span class="s">"Company"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">false</span>,
                <span class="k">"options"</span>: [],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            },
            "… 7 more, trimmed for the example"
        ],
        <span class="k">"values"</span>: {
            <span class="k">"address_title"</span>: <span class="s">"Mr"</span>,
            <span class="k">"address_firstname"</span>: <span class="s">"Alex"</span>,
            <span class="k">"address_lastname"</span>: <span class="s">"Marchand"</span>,
            <span class="k">"address_company"</span>: <span class="s">"Lilas SARL"</span>,
            <span class="k">"address_street"</span>: <span class="s">"12 rue des Lilas"</span>,
            <span class="k">"address_post_code"</span>: <span class="s">"44000"</span>,
            <span class="k">"address_city"</span>: <span class="s">"Nantes"</span>,
            <span class="k">"address_telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
            <span class="k">"address_country"</span>: <span class="s">"country_France_73"</span>,
            <span class="k">"address_state"</span>: <span class="s">""</span>,
            <span class="k">"address_vat"</span>: <span class="s">"FR00000000000"</span>
        },
        <span class="k">"country_name"</span>: <span class="s">"France"</span>,
        <span class="k">"state_name"</span>: <span class="s">""</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Add an address

POST /customers/**{id}**/addresses write since 6.6.0

Writes an address of a customer. Without an address id it creates one; with one it saves that one.

`types` says what the address is for, billing or shipping or both, and `default` makes it the default for those. An address is validated by the shop's own field rules, so a missing required field is refused rather than half-saved.

### Path

ParameterTypeDescription

idrequiredintegerThe customer.

### Body

FieldTypeDescription

fieldsrequiredobjectKeyed by address field namekey, the same keys the form returned in `values`.

typesstring\[\]Which of `billing` and `shipping` this address is for. Defaults to both.

defaultbooleanMake it the default for its types.

### Response expand all

FieldTypeDescription

idintegerThe HikaShop customer id, which is what every customer route takes.

cms\_idintegerThe Joomla or WordPress user id, `0` for a guest with no account.

namestring

emailstring

usernamestringThe login, empty for a guest.

typestring`registered` or `guest`.

blockedbooleanWhether the CMS account is disabled.

can\_edit\_accountbooleanWhether this operator may change the login and password of this particular account. False for an account above their own level, which is how a super user is protected from staff.

groups\_editablebooleanWhether this operator may change which groups the customer is in.

groupsobject\[\]The groups they are in.idinteger

titlestring

available\_groupsobject\[\]Every group, with whether this operator may put the customer into it, so a picker can grey out the rest rather than offering a refusal.idinteger

titlestring

assignablebooleanFalse for a group this operator may not grant.

createdintegerUnix timestamp of the first time the shop saw them.

addressesobject\[\]Their addresses, defaults first.idinteger

typesstring\[\]Which of `billing` and `shipping` it is used for.

namestring

companystring

streetstring

citystring

post\_codestring

telephonestring

defaultbooleanWhether it is the default for one of its types.

formattedobjectThe address laid out the way this shop lays addresses out, which depends on its address format setting.textstringSeveral lines, for an invoice or a label.

one\_linestringOne line, for a list.

ordersobject\[\]Their orders, newest first, enough to list them.idinteger

numberstringThe number the customer sees.

statusstringA namekey.

createdintegerUnix timestamp.

totalnumberTax included, in the order currency.

currency\_idintegerThat currency.

fieldsobject\[\]The definitions of your own customer fields.

custom\_fieldsobjectTheir values, keyed by namekey. The keys depend on the shop; `fields` says what they are.

custom\_field\_filesobjectFor a field holding a file, the file behind the value. Keyed the same way.

### Errors

CodeHTTPMeans

not\_found404No such customer or address, or the operator may not change them.

invalid\_fields400A field was rejected by its own rules.

invalid\_address400The address is not one the shop will accept, usually a missing required field.

```
curl -X POST "$SHOP/hikashop-api/v1/customers/{id}/addresses" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "fields": {
        "address_title": "Mr",
        "address_firstname": "Alex",
        "address_lastname": "Marchand",
        "address_street": "12 rue des Lilas",
        "address_post_code": "44000",
        "address_city": "Nantes",
        "address_telephone": "+33 2 00 00 00 00",
        "address_country": "country_Albania_2",
        "address_state": "state_Beratit_274"
    }
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">14</span>,
        <span class="k">"cms_id"</span>: <span class="n">156</span>,
        <span class="k">"name"</span>: <span class="s">"Admin"</span>,
        <span class="k">"email"</span>: <span class="s">"<joomla-hidden-mail base="" first="YnV5ZXI=" is-email="1" is-link="1" last="ZXhhbXBsZS50ZXN0" text="YnV5ZXJAZXhhbXBsZS50ZXN0">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>"</span>,
        <span class="k">"username"</span>: <span class="s">"admin"</span>,
        <span class="k">"type"</span>: <span class="s">"registered"</span>,
        <span class="k">"blocked"</span>: <span class="n">false</span>,
        <span class="k">"can_edit_account"</span>: <span class="n">false</span>,
        <span class="k">"groups_editable"</span>: <span class="n">false</span>,
        <span class="k">"groups"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">8</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>
            }
        ],
        <span class="k">"available_groups"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">1</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">9</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">6</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">7</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            "… 5 more, trimmed for the example"
        ],
        <span class="k">"created"</span>: <span class="n">1778653121</span>,
        <span class="k">"addresses"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">4372</span>,
                <span class="k">"types"</span>: [
                    "shipping"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">true</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            {
                <span class="k">"id"</span>: <span class="n">4371</span>,
                <span class="k">"types"</span>: [
                    "billing"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">true</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            {
                <span class="k">"id"</span>: <span class="n">4387</span>,
                <span class="k">"types"</span>: [
                    "billing"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">false</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            {
                <span class="k">"id"</span>: <span class="n">4380</span>,
                <span class="k">"types"</span>: [
                    "billing"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">false</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            "… 5 more, trimmed for the example"
        ],
        <span class="k">"orders"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">2</span>,
                <span class="k">"number"</span>: <span class="s">"TEST-VOTE-1"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1786877040</span>,
                <span class="k">"total"</span>: <span class="n">100</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">18</span>,
                <span class="k">"number"</span>: <span class="s">"U18"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1786358640</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">20</span>,
                <span class="k">"number"</span>: <span class="s">"X20"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1785840240</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">16</span>,
                <span class="k">"number"</span>: <span class="s">"S16"</span>,
                <span class="k">"status"</span>: <span class="s">"created"</span>,
                <span class="k">"created"</span>: <span class="n">1783345950</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            "… 96 more, trimmed for the example"
        ],
        <span class="k">"fields"</span>: [],
        <span class="k">"custom_fields"</span>: [],
        <span class="k">"custom_field_files"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Add an address

PUT /customers/**{id}**/addresses write since 6.6.0

Writes an address of a customer. Without an address id it creates one; with one it saves that one.

`types` says what the address is for, billing or shipping or both, and `default` makes it the default for those. An address is validated by the shop's own field rules, so a missing required field is refused rather than half-saved.

### Path

ParameterTypeDescription

idrequiredintegerThe customer.

### Body

FieldTypeDescription

fieldsrequiredobjectKeyed by address field namekey, the same keys the form returned in `values`.

typesstring\[\]Which of `billing` and `shipping` this address is for. Defaults to both.

defaultbooleanMake it the default for its types.

### Response expand all

FieldTypeDescription

idintegerThe HikaShop customer id, which is what every customer route takes.

cms\_idintegerThe Joomla or WordPress user id, `0` for a guest with no account.

namestring

emailstring

usernamestringThe login, empty for a guest.

typestring`registered` or `guest`.

blockedbooleanWhether the CMS account is disabled.

can\_edit\_accountbooleanWhether this operator may change the login and password of this particular account. False for an account above their own level, which is how a super user is protected from staff.

groups\_editablebooleanWhether this operator may change which groups the customer is in.

groupsobject\[\]The groups they are in.idinteger

titlestring

available\_groupsobject\[\]Every group, with whether this operator may put the customer into it, so a picker can grey out the rest rather than offering a refusal.idinteger

titlestring

assignablebooleanFalse for a group this operator may not grant.

createdintegerUnix timestamp of the first time the shop saw them.

addressesobject\[\]Their addresses, defaults first.idinteger

typesstring\[\]Which of `billing` and `shipping` it is used for.

namestring

companystring

streetstring

citystring

post\_codestring

telephonestring

defaultbooleanWhether it is the default for one of its types.

formattedobjectThe address laid out the way this shop lays addresses out, which depends on its address format setting.textstringSeveral lines, for an invoice or a label.

one\_linestringOne line, for a list.

ordersobject\[\]Their orders, newest first, enough to list them.idinteger

numberstringThe number the customer sees.

statusstringA namekey.

createdintegerUnix timestamp.

totalnumberTax included, in the order currency.

currency\_idintegerThat currency.

fieldsobject\[\]The definitions of your own customer fields.

custom\_fieldsobjectTheir values, keyed by namekey. The keys depend on the shop; `fields` says what they are.

custom\_field\_filesobjectFor a field holding a file, the file behind the value. Keyed the same way.

### Errors

CodeHTTPMeans

not\_found404No such customer or address, or the operator may not change them.

invalid\_fields400A field was rejected by its own rules.

invalid\_address400The address is not one the shop will accept, usually a missing required field.

```
curl -X PUT "$SHOP/hikashop-api/v1/customers/{id}/addresses" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "fields": {
        "address_title": "Mr",
        "address_firstname": "Alex",
        "address_lastname": "Marchand",
        "address_street": "12 rue des Lilas",
        "address_post_code": "44000",
        "address_city": "Nantes",
        "address_telephone": "+33 2 00 00 00 00",
        "address_country": "country_Albania_2",
        "address_state": "state_Beratit_274"
    }
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">14</span>,
        <span class="k">"cms_id"</span>: <span class="n">156</span>,
        <span class="k">"name"</span>: <span class="s">"Admin"</span>,
        <span class="k">"email"</span>: <span class="s">"<joomla-hidden-mail base="" first="YnV5ZXI=" is-email="1" is-link="1" last="ZXhhbXBsZS50ZXN0" text="YnV5ZXJAZXhhbXBsZS50ZXN0">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>"</span>,
        <span class="k">"username"</span>: <span class="s">"admin"</span>,
        <span class="k">"type"</span>: <span class="s">"registered"</span>,
        <span class="k">"blocked"</span>: <span class="n">false</span>,
        <span class="k">"can_edit_account"</span>: <span class="n">false</span>,
        <span class="k">"groups_editable"</span>: <span class="n">false</span>,
        <span class="k">"groups"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">8</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>
            }
        ],
        <span class="k">"available_groups"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">1</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">9</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">6</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">7</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            "… 5 more, trimmed for the example"
        ],
        <span class="k">"created"</span>: <span class="n">1778653121</span>,
        <span class="k">"addresses"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">4372</span>,
                <span class="k">"types"</span>: [
                    "shipping"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">true</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            {
                <span class="k">"id"</span>: <span class="n">4371</span>,
                <span class="k">"types"</span>: [
                    "billing"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">true</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            {
                <span class="k">"id"</span>: <span class="n">4388</span>,
                <span class="k">"types"</span>: [
                    "billing"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">false</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            {
                <span class="k">"id"</span>: <span class="n">4387</span>,
                <span class="k">"types"</span>: [
                    "billing"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">false</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            "… 6 more, trimmed for the example"
        ],
        <span class="k">"orders"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">2</span>,
                <span class="k">"number"</span>: <span class="s">"TEST-VOTE-1"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1786877040</span>,
                <span class="k">"total"</span>: <span class="n">100</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">18</span>,
                <span class="k">"number"</span>: <span class="s">"U18"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1786358640</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">20</span>,
                <span class="k">"number"</span>: <span class="s">"X20"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1785840240</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">16</span>,
                <span class="k">"number"</span>: <span class="s">"S16"</span>,
                <span class="k">"status"</span>: <span class="s">"created"</span>,
                <span class="k">"created"</span>: <span class="n">1783345950</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            "… 96 more, trimmed for the example"
        ],
        <span class="k">"fields"</span>: [],
        <span class="k">"custom_fields"</span>: [],
        <span class="k">"custom_field_files"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Save an address

POST /customers/**{customerId}**/addresses/**{addressId}** write since 6.6.0

Writes an address of a customer. Without an address id it creates one; with one it saves that one.

`types` says what the address is for, billing or shipping or both, and `default` makes it the default for those. An address is validated by the shop's own field rules, so a missing required field is refused rather than half-saved.

### Path

ParameterTypeDescription

customerIdrequiredintegerThe customer.

addressIdrequiredintegerThe address.

### Body

FieldTypeDescription

fieldsrequiredobjectKeyed by address field namekey, the same keys the form returned in `values`.

typesstring\[\]Which of `billing` and `shipping` this address is for. Defaults to both.

defaultbooleanMake it the default for its types.

### Response expand all

FieldTypeDescription

idintegerThe HikaShop customer id, which is what every customer route takes.

cms\_idintegerThe Joomla or WordPress user id, `0` for a guest with no account.

namestring

emailstring

usernamestringThe login, empty for a guest.

typestring`registered` or `guest`.

blockedbooleanWhether the CMS account is disabled.

can\_edit\_accountbooleanWhether this operator may change the login and password of this particular account. False for an account above their own level, which is how a super user is protected from staff.

groups\_editablebooleanWhether this operator may change which groups the customer is in.

groupsobject\[\]The groups they are in.idinteger

titlestring

available\_groupsobject\[\]Every group, with whether this operator may put the customer into it, so a picker can grey out the rest rather than offering a refusal.idinteger

titlestring

assignablebooleanFalse for a group this operator may not grant.

createdintegerUnix timestamp of the first time the shop saw them.

addressesobject\[\]Their addresses, defaults first.idinteger

typesstring\[\]Which of `billing` and `shipping` it is used for.

namestring

companystring

streetstring

citystring

post\_codestring

telephonestring

defaultbooleanWhether it is the default for one of its types.

formattedobjectThe address laid out the way this shop lays addresses out, which depends on its address format setting.textstringSeveral lines, for an invoice or a label.

one\_linestringOne line, for a list.

ordersobject\[\]Their orders, newest first, enough to list them.idinteger

numberstringThe number the customer sees.

statusstringA namekey.

createdintegerUnix timestamp.

totalnumberTax included, in the order currency.

currency\_idintegerThat currency.

fieldsobject\[\]The definitions of your own customer fields.

custom\_fieldsobjectTheir values, keyed by namekey. The keys depend on the shop; `fields` says what they are.

custom\_field\_filesobjectFor a field holding a file, the file behind the value. Keyed the same way.

### Errors

CodeHTTPMeans

not\_found404No such customer or address, or the operator may not change them.

invalid\_fields400A field was rejected by its own rules.

invalid\_address400The address is not one the shop will accept, usually a missing required field.

```
curl -X POST "$SHOP/hikashop-api/v1/customers/{id}/addresses/{id}" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "fields": {
        "address_title": "Mr",
        "address_firstname": "Alex",
        "address_lastname": "Marchand",
        "address_street": "12 rue des Lilas",
        "address_post_code": "44000",
        "address_city": "Nantes",
        "address_telephone": "+33 2 00 00 00 00",
        "address_country": "country_Albania_2",
        "address_state": "state_Beratit_274"
    }
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">14</span>,
        <span class="k">"cms_id"</span>: <span class="n">156</span>,
        <span class="k">"name"</span>: <span class="s">"Admin"</span>,
        <span class="k">"email"</span>: <span class="s">"<joomla-hidden-mail base="" first="YnV5ZXI=" is-email="1" is-link="1" last="ZXhhbXBsZS50ZXN0" text="YnV5ZXJAZXhhbXBsZS50ZXN0">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>"</span>,
        <span class="k">"username"</span>: <span class="s">"admin"</span>,
        <span class="k">"type"</span>: <span class="s">"registered"</span>,
        <span class="k">"blocked"</span>: <span class="n">false</span>,
        <span class="k">"can_edit_account"</span>: <span class="n">false</span>,
        <span class="k">"groups_editable"</span>: <span class="n">false</span>,
        <span class="k">"groups"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">8</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>
            }
        ],
        <span class="k">"available_groups"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">1</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">9</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">6</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">7</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            "… 5 more, trimmed for the example"
        ],
        <span class="k">"created"</span>: <span class="n">1778653121</span>,
        <span class="k">"addresses"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">4372</span>,
                <span class="k">"types"</span>: [
                    "shipping"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">true</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            {
                <span class="k">"id"</span>: <span class="n">4371</span>,
                <span class="k">"types"</span>: [
                    "billing"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">true</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            {
                <span class="k">"id"</span>: <span class="n">4388</span>,
                <span class="k">"types"</span>: [
                    "billing"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">false</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            {
                <span class="k">"id"</span>: <span class="n">4387</span>,
                <span class="k">"types"</span>: [
                    "billing"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">false</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            "… 6 more, trimmed for the example"
        ],
        <span class="k">"orders"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">2</span>,
                <span class="k">"number"</span>: <span class="s">"TEST-VOTE-1"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1786877040</span>,
                <span class="k">"total"</span>: <span class="n">100</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">18</span>,
                <span class="k">"number"</span>: <span class="s">"U18"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1786358640</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">20</span>,
                <span class="k">"number"</span>: <span class="s">"X20"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1785840240</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">16</span>,
                <span class="k">"number"</span>: <span class="s">"S16"</span>,
                <span class="k">"status"</span>: <span class="s">"created"</span>,
                <span class="k">"created"</span>: <span class="n">1783345950</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            "… 96 more, trimmed for the example"
        ],
        <span class="k">"fields"</span>: [],
        <span class="k">"custom_fields"</span>: [],
        <span class="k">"custom_field_files"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Save an address

PUT /customers/**{customerId}**/addresses/**{addressId}** write since 6.6.0

Writes an address of a customer. Without an address id it creates one; with one it saves that one.

`types` says what the address is for, billing or shipping or both, and `default` makes it the default for those. An address is validated by the shop's own field rules, so a missing required field is refused rather than half-saved.

### Path

ParameterTypeDescription

customerIdrequiredintegerThe customer.

addressIdrequiredintegerThe address.

### Body

FieldTypeDescription

fieldsrequiredobjectKeyed by address field namekey, the same keys the form returned in `values`.

typesstring\[\]Which of `billing` and `shipping` this address is for. Defaults to both.

defaultbooleanMake it the default for its types.

### Response expand all

FieldTypeDescription

idintegerThe HikaShop customer id, which is what every customer route takes.

cms\_idintegerThe Joomla or WordPress user id, `0` for a guest with no account.

namestring

emailstring

usernamestringThe login, empty for a guest.

typestring`registered` or `guest`.

blockedbooleanWhether the CMS account is disabled.

can\_edit\_accountbooleanWhether this operator may change the login and password of this particular account. False for an account above their own level, which is how a super user is protected from staff.

groups\_editablebooleanWhether this operator may change which groups the customer is in.

groupsobject\[\]The groups they are in.idinteger

titlestring

available\_groupsobject\[\]Every group, with whether this operator may put the customer into it, so a picker can grey out the rest rather than offering a refusal.idinteger

titlestring

assignablebooleanFalse for a group this operator may not grant.

createdintegerUnix timestamp of the first time the shop saw them.

addressesobject\[\]Their addresses, defaults first.idinteger

typesstring\[\]Which of `billing` and `shipping` it is used for.

namestring

companystring

streetstring

citystring

post\_codestring

telephonestring

defaultbooleanWhether it is the default for one of its types.

formattedobjectThe address laid out the way this shop lays addresses out, which depends on its address format setting.textstringSeveral lines, for an invoice or a label.

one\_linestringOne line, for a list.

ordersobject\[\]Their orders, newest first, enough to list them.idinteger

numberstringThe number the customer sees.

statusstringA namekey.

createdintegerUnix timestamp.

totalnumberTax included, in the order currency.

currency\_idintegerThat currency.

fieldsobject\[\]The definitions of your own customer fields.

custom\_fieldsobjectTheir values, keyed by namekey. The keys depend on the shop; `fields` says what they are.

custom\_field\_filesobjectFor a field holding a file, the file behind the value. Keyed the same way.

### Errors

CodeHTTPMeans

not\_found404No such customer or address, or the operator may not change them.

invalid\_fields400A field was rejected by its own rules.

invalid\_address400The address is not one the shop will accept, usually a missing required field.

```
curl -X PUT "$SHOP/hikashop-api/v1/customers/{id}/addresses/{id}" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "fields": {
        "address_title": "Mr",
        "address_firstname": "Alex",
        "address_lastname": "Marchand",
        "address_street": "12 rue des Lilas",
        "address_post_code": "44000",
        "address_city": "Nantes",
        "address_telephone": "+33 2 00 00 00 00",
        "address_country": "country_Albania_2",
        "address_state": "state_Beratit_274"
    }
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">14</span>,
        <span class="k">"cms_id"</span>: <span class="n">156</span>,
        <span class="k">"name"</span>: <span class="s">"Admin"</span>,
        <span class="k">"email"</span>: <span class="s">"<joomla-hidden-mail base="" first="YnV5ZXI=" is-email="1" is-link="1" last="ZXhhbXBsZS50ZXN0" text="YnV5ZXJAZXhhbXBsZS50ZXN0">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>"</span>,
        <span class="k">"username"</span>: <span class="s">"admin"</span>,
        <span class="k">"type"</span>: <span class="s">"registered"</span>,
        <span class="k">"blocked"</span>: <span class="n">false</span>,
        <span class="k">"can_edit_account"</span>: <span class="n">false</span>,
        <span class="k">"groups_editable"</span>: <span class="n">false</span>,
        <span class="k">"groups"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">8</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>
            }
        ],
        <span class="k">"available_groups"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">1</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">9</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">6</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">7</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            "… 5 more, trimmed for the example"
        ],
        <span class="k">"created"</span>: <span class="n">1778653121</span>,
        <span class="k">"addresses"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">4372</span>,
                <span class="k">"types"</span>: [
                    "shipping"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">true</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            {
                <span class="k">"id"</span>: <span class="n">4371</span>,
                <span class="k">"types"</span>: [
                    "billing"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">true</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            {
                <span class="k">"id"</span>: <span class="n">4388</span>,
                <span class="k">"types"</span>: [
                    "billing"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">false</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            {
                <span class="k">"id"</span>: <span class="n">4387</span>,
                <span class="k">"types"</span>: [
                    "billing"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">false</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            "… 6 more, trimmed for the example"
        ],
        <span class="k">"orders"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">2</span>,
                <span class="k">"number"</span>: <span class="s">"TEST-VOTE-1"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1786877040</span>,
                <span class="k">"total"</span>: <span class="n">100</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">18</span>,
                <span class="k">"number"</span>: <span class="s">"U18"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1786358640</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">20</span>,
                <span class="k">"number"</span>: <span class="s">"X20"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1785840240</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">16</span>,
                <span class="k">"number"</span>: <span class="s">"S16"</span>,
                <span class="k">"status"</span>: <span class="s">"created"</span>,
                <span class="k">"created"</span>: <span class="n">1783345950</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            "… 96 more, trimmed for the example"
        ],
        <span class="k">"fields"</span>: [],
        <span class="k">"custom_fields"</span>: [],
        <span class="k">"custom_field_files"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Delete an address

DELETE /customers/**{id}**/addresses write since 6.6.0

Removes an address from a customer. Orders that used it keep their own copy of it.

### Path

ParameterTypeDescription

idrequiredintegerThe customer.

### Response expand all

FieldTypeDescription

idintegerThe HikaShop customer id, which is what every customer route takes.

cms\_idintegerThe Joomla or WordPress user id, `0` for a guest with no account.

namestring

emailstring

usernamestringThe login, empty for a guest.

typestring`registered` or `guest`.

blockedbooleanWhether the CMS account is disabled.

can\_edit\_accountbooleanWhether this operator may change the login and password of this particular account. False for an account above their own level, which is how a super user is protected from staff.

groups\_editablebooleanWhether this operator may change which groups the customer is in.

groupsobject\[\]The groups they are in.idinteger

titlestring

available\_groupsobject\[\]Every group, with whether this operator may put the customer into it, so a picker can grey out the rest rather than offering a refusal.idinteger

titlestring

assignablebooleanFalse for a group this operator may not grant.

createdintegerUnix timestamp of the first time the shop saw them.

addressesobject\[\]Their addresses, defaults first.idinteger

typesstring\[\]Which of `billing` and `shipping` it is used for.

namestring

companystring

streetstring

citystring

post\_codestring

telephonestring

defaultbooleanWhether it is the default for one of its types.

formattedobjectThe address laid out the way this shop lays addresses out, which depends on its address format setting.textstringSeveral lines, for an invoice or a label.

one\_linestringOne line, for a list.

ordersobject\[\]Their orders, newest first, enough to list them.idinteger

numberstringThe number the customer sees.

statusstringA namekey.

createdintegerUnix timestamp.

totalnumberTax included, in the order currency.

currency\_idintegerThat currency.

fieldsobject\[\]The definitions of your own customer fields.

custom\_fieldsobjectTheir values, keyed by namekey. The keys depend on the shop; `fields` says what they are.

custom\_field\_filesobjectFor a field holding a file, the file behind the value. Keyed the same way.

### Errors

CodeHTTPMeans

not\_found404No such customer or address, or the operator may not change them.

```
curl -X DELETE "$SHOP/hikashop-api/v1/customers/{id}/addresses/{id}" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">14</span>,
        <span class="k">"cms_id"</span>: <span class="n">156</span>,
        <span class="k">"name"</span>: <span class="s">"Admin"</span>,
        <span class="k">"email"</span>: <span class="s">"<joomla-hidden-mail base="" first="YnV5ZXI=" is-email="1" is-link="1" last="ZXhhbXBsZS50ZXN0" text="YnV5ZXJAZXhhbXBsZS50ZXN0">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>"</span>,
        <span class="k">"username"</span>: <span class="s">"admin"</span>,
        <span class="k">"type"</span>: <span class="s">"registered"</span>,
        <span class="k">"blocked"</span>: <span class="n">false</span>,
        <span class="k">"can_edit_account"</span>: <span class="n">false</span>,
        <span class="k">"groups_editable"</span>: <span class="n">false</span>,
        <span class="k">"groups"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">8</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>
            }
        ],
        <span class="k">"available_groups"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">1</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">9</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">6</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">7</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            "… 5 more, trimmed for the example"
        ],
        <span class="k">"created"</span>: <span class="n">1778653121</span>,
        <span class="k">"addresses"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">4372</span>,
                <span class="k">"types"</span>: [
                    "shipping"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">true</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            {
                <span class="k">"id"</span>: <span class="n">4371</span>,
                <span class="k">"types"</span>: [
                    "billing"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">true</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            {
                <span class="k">"id"</span>: <span class="n">4388</span>,
                <span class="k">"types"</span>: [
                    "billing"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">false</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            {
                <span class="k">"id"</span>: <span class="n">4387</span>,
                <span class="k">"types"</span>: [
                    "billing"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">false</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            "… 6 more, trimmed for the example"
        ],
        <span class="k">"orders"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">2</span>,
                <span class="k">"number"</span>: <span class="s">"TEST-VOTE-1"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1786877040</span>,
                <span class="k">"total"</span>: <span class="n">100</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">18</span>,
                <span class="k">"number"</span>: <span class="s">"U18"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1786358640</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">20</span>,
                <span class="k">"number"</span>: <span class="s">"X20"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1785840240</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">16</span>,
                <span class="k">"number"</span>: <span class="s">"S16"</span>,
                <span class="k">"status"</span>: <span class="s">"created"</span>,
                <span class="k">"created"</span>: <span class="n">1783345950</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            "… 96 more, trimmed for the example"
        ],
        <span class="k">"fields"</span>: [],
        <span class="k">"custom_fields"</span>: [],
        <span class="k">"custom_field_files"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Delete an address

DELETE /customers/**{customerId}**/addresses/**{addressId}** write since 6.6.0

Removes an address from a customer. Orders that used it keep their own copy of it.

### Path

ParameterTypeDescription

customerIdrequiredintegerThe customer.

addressIdrequiredintegerThe address.

### Response expand all

FieldTypeDescription

idintegerThe HikaShop customer id, which is what every customer route takes.

cms\_idintegerThe Joomla or WordPress user id, `0` for a guest with no account.

namestring

emailstring

usernamestringThe login, empty for a guest.

typestring`registered` or `guest`.

blockedbooleanWhether the CMS account is disabled.

can\_edit\_accountbooleanWhether this operator may change the login and password of this particular account. False for an account above their own level, which is how a super user is protected from staff.

groups\_editablebooleanWhether this operator may change which groups the customer is in.

groupsobject\[\]The groups they are in.idinteger

titlestring

available\_groupsobject\[\]Every group, with whether this operator may put the customer into it, so a picker can grey out the rest rather than offering a refusal.idinteger

titlestring

assignablebooleanFalse for a group this operator may not grant.

createdintegerUnix timestamp of the first time the shop saw them.

addressesobject\[\]Their addresses, defaults first.idinteger

typesstring\[\]Which of `billing` and `shipping` it is used for.

namestring

companystring

streetstring

citystring

post\_codestring

telephonestring

defaultbooleanWhether it is the default for one of its types.

formattedobjectThe address laid out the way this shop lays addresses out, which depends on its address format setting.textstringSeveral lines, for an invoice or a label.

one\_linestringOne line, for a list.

ordersobject\[\]Their orders, newest first, enough to list them.idinteger

numberstringThe number the customer sees.

statusstringA namekey.

createdintegerUnix timestamp.

totalnumberTax included, in the order currency.

currency\_idintegerThat currency.

fieldsobject\[\]The definitions of your own customer fields.

custom\_fieldsobjectTheir values, keyed by namekey. The keys depend on the shop; `fields` says what they are.

custom\_field\_filesobjectFor a field holding a file, the file behind the value. Keyed the same way.

### Errors

CodeHTTPMeans

not\_found404No such customer or address, or the operator may not change them.

```
curl -X DELETE "$SHOP/hikashop-api/v1/customers/{id}/addresses/{id}" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">14</span>,
        <span class="k">"cms_id"</span>: <span class="n">156</span>,
        <span class="k">"name"</span>: <span class="s">"Admin"</span>,
        <span class="k">"email"</span>: <span class="s">"<joomla-hidden-mail base="" first="YnV5ZXI=" is-email="1" is-link="1" last="ZXhhbXBsZS50ZXN0" text="YnV5ZXJAZXhhbXBsZS50ZXN0">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>"</span>,
        <span class="k">"username"</span>: <span class="s">"admin"</span>,
        <span class="k">"type"</span>: <span class="s">"registered"</span>,
        <span class="k">"blocked"</span>: <span class="n">false</span>,
        <span class="k">"can_edit_account"</span>: <span class="n">false</span>,
        <span class="k">"groups_editable"</span>: <span class="n">false</span>,
        <span class="k">"groups"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">8</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>
            }
        ],
        <span class="k">"available_groups"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">1</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">9</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">6</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">7</span>,
                <span class="k">"title"</span>: <span class="s">"Mr"</span>,
                <span class="k">"assignable"</span>: <span class="n">false</span>
            },
            "… 5 more, trimmed for the example"
        ],
        <span class="k">"created"</span>: <span class="n">1778653121</span>,
        <span class="k">"addresses"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">4372</span>,
                <span class="k">"types"</span>: [
                    "shipping"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">true</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            {
                <span class="k">"id"</span>: <span class="n">4371</span>,
                <span class="k">"types"</span>: [
                    "billing"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">true</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            {
                <span class="k">"id"</span>: <span class="n">4388</span>,
                <span class="k">"types"</span>: [
                    "billing"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">false</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            {
                <span class="k">"id"</span>: <span class="n">4387</span>,
                <span class="k">"types"</span>: [
                    "billing"
                ],
                <span class="k">"name"</span>: <span class="s">"Test Buyer"</span>,
                <span class="k">"company"</span>: <span class="s">"Lilas SARL"</span>,
                <span class="k">"street"</span>: <span class="s">"12 rue des Lilas"</span>,
                <span class="k">"city"</span>: <span class="s">"Nantes"</span>,
                <span class="k">"post_code"</span>: <span class="s">"44000"</span>,
                <span class="k">"telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
                <span class="k">"default"</span>: <span class="n">false</span>,
                <span class="k">"formatted"</span>: {
                    <span class="k">"text"</span>: <span class="s">"Alex Marchand\r\n12 rue des Lilas\r\n44000 Nantes\r\nFrance"</span>,
                    <span class="k">"one_line"</span>: <span class="s">"Marchand Alex - 12 rue des Lilas, Nantes (France)"</span>
                }
            },
            "… 6 more, trimmed for the example"
        ],
        <span class="k">"orders"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">2</span>,
                <span class="k">"number"</span>: <span class="s">"TEST-VOTE-1"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1786877040</span>,
                <span class="k">"total"</span>: <span class="n">100</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">18</span>,
                <span class="k">"number"</span>: <span class="s">"U18"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1786358640</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">20</span>,
                <span class="k">"number"</span>: <span class="s">"X20"</span>,
                <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
                <span class="k">"created"</span>: <span class="n">1785840240</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">16</span>,
                <span class="k">"number"</span>: <span class="s">"S16"</span>,
                <span class="k">"status"</span>: <span class="s">"created"</span>,
                <span class="k">"created"</span>: <span class="n">1783345950</span>,
                <span class="k">"total"</span>: <span class="n">14.99</span>,
                <span class="k">"currency_id"</span>: <span class="n">1</span>
            },
            "… 96 more, trimmed for the example"
        ],
        <span class="k">"fields"</span>: [],
        <span class="k">"custom_fields"</span>: [],
        <span class="k">"custom_field_files"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Redeem a pairing code

POST /pair public since 6.6.0

Exchanges a single-use code, generated in **System &gt; App Devices** of the shop's backend, for the device's own token. This is the only route that answers without one.

The token comes back **once**. Only its hash is stored, so a lost token is re-paired, never recovered. Attempts are rate limited per address.

### Body

FieldTypeDescription

coderequiredstringThe pairing code as shown in the backend. Case and spacing are normalised, so the grouping dash is optional.

device\_namestringWhat to call this device in the device list. Defaults to `Device`.

platformstringA free label kept for the listing. Anything that is not a letter, a digit, a dash or an underscore is stripped.

### Response expand all

FieldTypeDescription

tokenstringSend this as the bearer token from now on. It is not retrievable again.

scopesstring\[\]`read`, and `write` when the code granted it.

device\_idintegerThe row in the device list, which is what you revoke later.

### Errors

CodeHTTPMeans

invalid\_request400No code was sent.

invalid\_code403The code is unknown, already used, or expired.

too\_many\_requests429Too many attempts from this address.

```
curl -X POST "$SHOP/hikashop-api/v1/pair" \
  -H "Content-Type: application/json" \
  -d '{
    "device_name": "Counter tablet",
    "platform": "android",
    "code": "9CED9F"
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"token"</span>: <span class="s">"hk_dev_3f9c1a……"</span>,
        <span class="k">"scopes"</span>: [
            "read",
            "write"
        ],
        <span class="k">"device_id"</span>: <span class="n">129</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## List products

GET /products read since 6.6.0

The catalogue as the backend sees it, unpublished products included, which is what makes this different from the front end.

Variants are not listed on their own. A parent carries `has_variants`, and `GET /products/{id}` returns the variants themselves.

### Query

ParameterTypeDescription

startintegerOffset into the result set. Defaults to `0`.

limitintegerPage size. Defaults to `20` and is capped at `100`.

searchstringMatches the product name and the product code.

idsstringComma separated product ids, to resolve a known set in one call.

category\_idintegerRestrict to one category.

### Response a list expand all

FieldTypeDescription

idinteger

namestring

codestringThe SKU. Unique within the shop.

quantityinteger`-1` when the product does not track stock, which is not the same as `0`.

publishedboolean

has\_variantsbooleanAsk `GET /products/{id}` for the variants themselves.

imagestring\|nullAbsolute URL of the main image, or `null`.

pricenumber\|null`null` when the product has no price row at all.

currency\_idintegerA row in the shop's currency table, not an ISO code.

custom\_fieldsobjectThe listing values of this product, keyed by field namekey. The keys are whatever this shop has configured, so there is no list to give. `fields` in the envelope says what they are.

### Envelope meta

FieldTypeDescription

startintegerEchoes the offset used.

limitintegerEchoes the page size used.

totalintegerRows matching the filter, before paging. This is how you know there is another page.

fieldsobject\[\]The custom fields shown on listings, so a client can label the values it just received.

```
curl "$SHOP/hikashop-api/v1/products?limit=2" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: [
        {
            <span class="k">"id"</span>: <span class="n">8731</span>,
            <span class="k">"name"</span>: <span class="s">"Anodised Film Camera — 35 mm"</span>,
            <span class="k">"code"</span>: <span class="s">"DEMO-0073"</span>,
            <span class="k">"quantity"</span>: <span class="n">79</span>,
            <span class="k">"published"</span>: <span class="n">true</span>,
            <span class="k">"has_variants"</span>: <span class="n">false</span>,
            <span class="k">"image"</span>: <span class="s">"http://localhost:<span class="n">8080</span>/joomla6_ext/images/com_hikashop/upload/demo-0073.png"</span>,
            <span class="k">"price"</span>: <span class="n">71.21</span>,
            <span class="k">"currency_id"</span>: <span class="n">1</span>,
            <span class="k">"custom_fields"</span>: []
        },
        {
            <span class="k">"id"</span>: <span class="n">8816</span>,
            <span class="k">"name"</span>: <span class="s">"Anodised Headphones"</span>,
            <span class="k">"code"</span>: <span class="s">"DEMO-0133"</span>,
            <span class="k">"quantity"</span>: <span class="n">14</span>,
            <span class="k">"published"</span>: <span class="n">true</span>,
            <span class="k">"has_variants"</span>: <span class="n">false</span>,
            <span class="k">"image"</span>: <span class="s">"http://localhost:<span class="n">8080</span>/joomla6_ext/images/com_hikashop/upload/demo-0133.png"</span>,
            <span class="k">"price"</span>: <span class="n">317.13</span>,
            <span class="k">"currency_id"</span>: <span class="n">1</span>,
            <span class="k">"custom_fields"</span>: []
        }
    ],
    <span class="k">"meta"</span>: {
        <span class="k">"start"</span>: <span class="n">0</span>,
        <span class="k">"limit"</span>: <span class="n">2</span>,
        <span class="k">"total"</span>: <span class="n">309</span>,
        <span class="k">"fields"</span>: []
    },
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## List orders

GET /orders read since 6.6.0

The orders the operator may see, newest first. It is the listing the app's order screen is built on, so it carries just enough to draw a row and no more; ask for one order when you need the rest.

### Query

ParameterTypeDescription

startintegerOffset. Defaults to `0`.

limitintegerDefaults to `20`, capped at `100`.

searchstringMatches the order number and the customer.

statusstringA status namekey, as listed by `GET /statuses`.

### Response a list expand all

FieldTypeDescription

idintegerThe order id, which is what every other order route takes.

numberstringThe order number the customer sees, which is not the id.

statusstringA namekey, not a label. `GET /statuses` translates it.

createdintegerUnix timestamp.

totalnumberWhat the customer owes, tax included, in the order currency.

currency\_idintegerThe order keeps the currency it was placed in, which need not be the shop default.

customerobjectEnough to name the buyer in a list.namestring

emailstring

custom\_fieldsobjectThe listing values of your own order fields, keyed by namekey. The keys are whatever this shop has configured; `fields` in the envelope says what they are.

### Envelope meta

FieldTypeDescription

startintegerEchoes the offset used.

limitintegerEchoes the page size used.

totalintegerOrders matching the filter, before paging.

fieldsobject\[\]The definitions behind `custom_fields`.

```
curl "$SHOP/hikashop-api/v1/orders?limit=2" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: [
        {
            <span class="k">"id"</span>: <span class="n">2</span>,
            <span class="k">"number"</span>: <span class="s">"TEST-VOTE-1"</span>,
            <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
            <span class="k">"created"</span>: <span class="n">1786877040</span>,
            <span class="k">"total"</span>: <span class="n">100</span>,
            <span class="k">"currency_id"</span>: <span class="n">1</span>,
            <span class="k">"customer"</span>: {
                <span class="k">"name"</span>: <span class="s">"Admin"</span>,
                <span class="k">"email"</span>: <span class="s">"<joomla-hidden-mail base="" first="YnV5ZXI=" is-email="1" is-link="1" last="ZXhhbXBsZS50ZXN0" text="YnV5ZXJAZXhhbXBsZS50ZXN0">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>"</span>
            },
            <span class="k">"custom_fields"</span>: []
        },
        {
            <span class="k">"id"</span>: <span class="n">18</span>,
            <span class="k">"number"</span>: <span class="s">"U18"</span>,
            <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
            <span class="k">"created"</span>: <span class="n">1786358640</span>,
            <span class="k">"total"</span>: <span class="n">14.99</span>,
            <span class="k">"currency_id"</span>: <span class="n">1</span>,
            <span class="k">"customer"</span>: {
                <span class="k">"name"</span>: <span class="s">"Admin"</span>,
                <span class="k">"email"</span>: <span class="s">"<joomla-hidden-mail base="" first="YnV5ZXI=" is-email="1" is-link="1" last="ZXhhbXBsZS50ZXN0" text="YnV5ZXJAZXhhbXBsZS50ZXN0">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>"</span>
            },
            <span class="k">"custom_fields"</span>: []
        }
    ],
    <span class="k">"meta"</span>: {
        <span class="k">"start"</span>: <span class="n">0</span>,
        <span class="k">"limit"</span>: <span class="n">2</span>,
        <span class="k">"total"</span>: <span class="n">640</span>,
        <span class="k">"fields"</span>: []
    },
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Read one order

GET /orders/**{id}** read since 6.6.0

The whole order: its lines, its totals, its addresses, its history and your own fields.

Money is in the currency the order was placed in, which is not necessarily the shop's. Do not convert it: an order is a record of what was agreed at the time.

### Path

ParameterTypeDescription

idrequiredintegerThe order id.

### Response expand all

FieldTypeDescription

idinteger

numberstringThe number the customer sees.

statusstringA namekey.

createdintegerUnix timestamp.

modifiedintegerUnix timestamp of the last change.

currency\_idintegerThe currency the order was placed in.

totalsobjectThe figures. See the shape below.totalnumberWhat the customer owes, tax included.

discountnumberThe discount applied, as a positive figure already subtracted.

shippingnumberThe shipping charged.

paymentnumberThe payment fee charged.

taxnumberThe tax within the total, not on top of it.

customerobjectWho placed it.namestring

emailstring

payment\_methodstringHow it was paid, as the shop names it.

shipping\_methodstringHow it ships.

invoice\_numberstringEmpty until an invoice has been issued.

invoice\_createdinteger\|nullUnix timestamp of the invoice.

itemsobject\[\]The lines: `id`, `name`, `code`, `quantity`, `price`, `tax` and whether the line can still be edited.idintegerThe line id, which is what `PUT /orders/{id}/products/{lineId}` takes. It is not the product id.

namestringThe product as it was named when ordered, which may since have changed.

codestringIts SKU at the time.

quantityinteger

pricenumberUnit price, tax excluded, as agreed at the time.

taxnumberTax on the line.

editablebooleanFalse once the line can no longer be changed, for instance on a shipped order.

billing\_addressobject\|nullThe address as it was at the time, `null` when there is none. It is a copy, not a pointer at the customer's current address.

shipping\_addressobject\|nullThe same, for delivery.

shipping\_address\_overridebooleanWhether the delivery address was set apart from the billing one.

historyobject\[\]What has happened to the order, oldest first.statusstringThe namekey it moved to.

createdintegerUnix timestamp.

typestringWhat caused it: a payment notification, an operator, the shop itself.

reasonstringThe note recorded with the change, when there was one.

notifiedbooleanWhether the customer was emailed about it.

fieldsobject\[\]The definitions of your own order fields.namekeystringThe key its value is stored under.

typestringWhat to render: `text`, `radio`, `singledropdown`, `file`, and the rest.

raw\_typestringHikaShop's own name for the type.

labelstringTranslated into the operator's language.

defaultstringThe value used when none is given.

requiredbooleanWhether the shop refuses to save without it.

optionsobject\[\]The choices, for a field that has them.valuestringWhat to send back when this choice is picked.

labelstringWhat to show.

label\_keystringThe translation key behind the label, when there is one.

multiplebooleanWhether more than one may be chosen.

translatablebooleanWhether its value can be translated.

upload\_dirstringFor a file field, where its uploads are kept.

allowed\_extensionsstringFor a file field, the extensions it accepts. Empty means the shop default.

date\_formatstringFor a date field, the format it is stored in.

custom\_fieldsobjectTheir values, keyed by namekey. The keys depend on the shop; `fields` says what they are.

custom\_field\_filesobjectFor a field holding a file, the file behind the value. Keyed the same way.

feesobjectThe `discount`, `shipping` and `payment` amounts, which is what `PUT /orders/{id}/fees` writes.  discountobjectIts `amount`, its `tax`, the `tax_namekeys` behind that tax, and the coupon `code` when one was used.amountnumberA positive figure, already subtracted from the total.

taxnumberThe tax on it.

tax\_namekeysstring\[\]Which tax rates that came from.

codestringThe coupon code, empty for a discount applied by hand.

shippingobjectThe shipping charge and what carried it.amountnumberTax excluded.

taxnumberThe tax on it.

tax\_namekeysstring\[\]Which tax rates that came from.

methodstringThe plugin that handled it.

method\_namestringAs the merchant named it.

paymentobjectThe payment fee and what took it.amountnumberTax excluded.

taxnumberThe tax on it.

tax\_namekeysstring\[\]Which tax rates that came from.

methodstringThe plugin that took it.

method\_namestringAs the merchant named it.

tax\_ratesobject\[\]The rates that made up the tax, each with its namekey and rate, so a total can be explained rather than only shown.namekeystringThe tax rate as the shop names it.

ratenumberAs a fraction, so `0.1` is ten percent.

sectionsobject\[\]Information other plugins show on this record, each with a `key`, a `title` and `rows` (`label`, `value`, and optionally `url`, `badge` and `ref`). Empty when no plugin adds any; on a customer, core adds their paid downloads. See the guide on adding information and settings.

extensionsobject\[\]Settings other plugins keep on this record, in groups (`key`, `title`, `fields`), each field described like a custom field plus its current `value`. Send changes back as `extensions` with the record's save. Empty when no plugin adds any.

```
curl "$SHOP/hikashop-api/v1/orders/{id}" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">5630</span>,
        <span class="k">"number"</span>: <span class="s">"S5630"</span>,
        <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
        <span class="k">"created"</span>: <span class="n">1738143180</span>,
        <span class="k">"modified"</span>: <span class="n">1790620951</span>,
        <span class="k">"currency_id"</span>: <span class="n">1</span>,
        <span class="k">"totals"</span>: {
            <span class="k">"total"</span>: <span class="n">313.92</span>,
            <span class="k">"discount"</span>: <span class="n">0</span>,
            <span class="k">"shipping"</span>: <span class="n">6.9</span>,
            <span class="k">"payment"</span>: <span class="n">0</span>,
            <span class="k">"tax"</span>: <span class="n">0</span>
        },
        <span class="k">"customer"</span>: {
            <span class="k">"name"</span>: <span class="s">"Admin"</span>,
            <span class="k">"email"</span>: <span class="s">"<joomla-hidden-mail base="" first="YnV5ZXI=" is-email="1" is-link="1" last="ZXhhbXBsZS50ZXN0" text="YnV5ZXJAZXhhbXBsZS50ZXN0">This email address is being protected from spambots. You need JavaScript enabled to view it.</joomla-hidden-mail>"</span>
        },
        <span class="k">"payment_method"</span>: <span class="s">"paypalcheckout"</span>,
        <span class="k">"shipping_method"</span>: <span class="s">"manual"</span>,
        <span class="k">"invoice_number"</span>: <span class="s">"B5630"</span>,
        <span class="k">"invoice_created"</span>: <span class="n">1738143180</span>,
        <span class="k">"items"</span>: [
            {
                <span class="k">"id"</span>: <span class="n">20630</span>,
                <span class="k">"name"</span>: <span class="s">"Nordic Design item"</span>,
                <span class="k">"code"</span>: <span class="s">"SEED-7-44"</span>,
                <span class="k">"quantity"</span>: <span class="n">1</span>,
                <span class="k">"price"</span>: <span class="n">307.02</span>,
                <span class="k">"tax"</span>: <span class="n">0</span>,
                <span class="k">"editable"</span>: <span class="n">true</span>
            },
            {
                <span class="k">"id"</span>: <span class="n">20642</span>,
                <span class="k">"name"</span>: <span class="s">"Test Product (Vendor 2)"</span>,
                <span class="k">"code"</span>: <span class="s">"TEST001"</span>,
                <span class="k">"quantity"</span>: <span class="n">1</span>,
                <span class="k">"price"</span>: <span class="n">0</span>,
                <span class="k">"tax"</span>: <span class="n">0</span>,
                <span class="k">"editable"</span>: <span class="n">true</span>
            }
        ],
        <span class="k">"billing_address"</span>: <span class="n">null</span>,
        <span class="k">"shipping_address"</span>: <span class="n">null</span>,
        <span class="k">"shipping_address_override"</span>: [],
        <span class="k">"history"</span>: [],
        <span class="k">"fields"</span>: [
            {
                <span class="k">"namekey"</span>: <span class="s">"hstestfile1755"</span>,
                <span class="k">"type"</span>: <span class="s">"ajaxfile"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"ajaxfile"</span>,
                <span class="k">"label"</span>: <span class="s">"Test attachment"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">false</span>,
                <span class="k">"options"</span>: [],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            },
            {
                <span class="k">"namekey"</span>: <span class="s">"hstestfile1859"</span>,
                <span class="k">"type"</span>: <span class="s">"ajaxfile"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"ajaxfile"</span>,
                <span class="k">"label"</span>: <span class="s">"Test attachment"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">false</span>,
                <span class="k">"options"</span>: [],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            },
            {
                <span class="k">"namekey"</span>: <span class="s">"hstestfile26994"</span>,
                <span class="k">"type"</span>: <span class="s">"ajaxfile"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"ajaxfile"</span>,
                <span class="k">"label"</span>: <span class="s">"Test attachment"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">false</span>,
                <span class="k">"options"</span>: [],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            },
            {
                <span class="k">"namekey"</span>: <span class="s">"hstestfile28016"</span>,
                <span class="k">"type"</span>: <span class="s">"ajaxfile"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"ajaxfile"</span>,
                <span class="k">"label"</span>: <span class="s">"Test attachment"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">false</span>,
                <span class="k">"options"</span>: [],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            },
            "… 1 more, trimmed for the example"
        ],
        <span class="k">"custom_fields"</span>: {
            <span class="k">"hstestfile1755"</span>: <span class="n">null</span>,
            <span class="k">"hstestfile1859"</span>: <span class="n">null</span>,
            <span class="k">"hstestfile26994"</span>: <span class="n">null</span>,
            <span class="k">"hstestfile28016"</span>: <span class="n">null</span>,
            <span class="k">"hstestfile27610"</span>: <span class="n">null</span>
        },
        <span class="k">"custom_field_files"</span>: [],
        <span class="k">"fees"</span>: {
            <span class="k">"discount"</span>: {
                <span class="k">"amount"</span>: <span class="n">0</span>,
                <span class="k">"tax"</span>: <span class="n">0</span>,
                <span class="k">"tax_namekeys"</span>: [],
                <span class="k">"code"</span>: <span class="s">""</span>
            },
            <span class="k">"shipping"</span>: {
                <span class="k">"amount"</span>: <span class="n">6.9</span>,
                <span class="k">"tax"</span>: <span class="n">0</span>,
                <span class="k">"tax_namekeys"</span>: [],
                <span class="k">"method"</span>: <span class="s">"manual"</span>,
                <span class="k">"method_name"</span>: <span class="s">"Vendor 2 only shipping"</span>
            },
            <span class="k">"payment"</span>: {
                <span class="k">"amount"</span>: <span class="n">0</span>,
                <span class="k">"tax"</span>: <span class="n">0</span>,
                <span class="k">"tax_namekeys"</span>: [],
                <span class="k">"method"</span>: <span class="s">"paypalcheckout"</span>,
                <span class="k">"method_name"</span>: <span class="s">"PayPal Checkout Express Test"</span>
            }
        },
        <span class="k">"tax_rates"</span>: [
            {
                <span class="k">"namekey"</span>: <span class="s">"apptest_vat10"</span>,
                <span class="k">"rate"</span>: <span class="n">0.1</span>
            },
            {
                <span class="k">"namekey"</span>: <span class="s">"apptest_vat20"</span>,
                <span class="k">"rate"</span>: <span class="n">0.2</span>
            },
            {
                <span class="k">"namekey"</span>: <span class="s">"gst"</span>,
                <span class="k">"rate"</span>: <span class="n">0.06</span>
            },
            {
                <span class="k">"namekey"</span>: <span class="s">"recargo 5,2%"</span>,
                <span class="k">"rate"</span>: <span class="n">0.052</span>
            },
            "… 1 more, trimmed for the example"
        ],
        <span class="k">"sections"</span>: [],
        <span class="k">"extensions"</span>: []
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Set the order fees

PUT /orders/**{id}**/fees write since 6.6.0

Replaces the discount, shipping and payment amounts and re-totals the order, so a client does not have to compute a total itself and risk disagreeing with the shop.

What you do not send keeps its current value.

### Path

ParameterTypeDescription

idrequiredintegerThe order id.

### Body

FieldTypeDescription

feesrequiredobjectAny of `discount`, `shipping` and `payment`, each an object with at least an `amount`, tax excluded. A discount is a positive figure and is subtracted.

### Response expand all

FieldTypeDescription

idinteger

feesobjectThe discount, shipping and payment amounts of the order.  discountobjectIts `amount`, its `tax`, the `tax_namekeys` behind that tax, and the coupon `code` when one was used.amountnumberA positive figure, already subtracted from the total.

taxnumberThe tax on it.

tax\_namekeysstring\[\]Which tax rates that came from.

codestringThe coupon code, empty for a discount applied by hand.

shippingobjectThe shipping charge and what carried it.amountnumberTax excluded.

taxnumberThe tax on it.

tax\_namekeysstring\[\]Which tax rates that came from.

methodstringThe plugin that handled it.

method\_namestringAs the merchant named it.

paymentobjectThe payment fee and what took it.amountnumberTax excluded.

taxnumberThe tax on it.

tax\_namekeysstring\[\]Which tax rates that came from.

methodstringThe plugin that took it.

method\_namestringAs the merchant named it.

totalsobjectThe order totalled, so a client need not compute it and disagree with the shop.totalnumberWhat the customer owes, tax included.

discountnumberThe discount applied, as a positive figure already subtracted.

shippingnumberThe shipping charged.

paymentnumberThe payment fee charged.

taxnumberThe tax within the total, not on top of it.

### Errors

CodeHTTPMeans

not\_found404No such order, or the operator may not change it.

save\_failed500The order could not be saved.

```
curl -X PUT "$SHOP/hikashop-api/v1/orders/{id}/fees" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "fees": {
        "shipping": {
            "amount": 4.9
        }
    }
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">5630</span>,
        <span class="k">"fees"</span>: {
            <span class="k">"discount"</span>: {
                <span class="k">"amount"</span>: <span class="n">0</span>,
                <span class="k">"tax"</span>: <span class="n">0</span>,
                <span class="k">"tax_namekeys"</span>: [],
                <span class="k">"code"</span>: <span class="s">""</span>
            },
            <span class="k">"shipping"</span>: {
                <span class="k">"amount"</span>: <span class="n">4.9</span>,
                <span class="k">"tax"</span>: <span class="n">0</span>,
                <span class="k">"tax_namekeys"</span>: [],
                <span class="k">"method"</span>: <span class="s">"manual"</span>,
                <span class="k">"method_name"</span>: <span class="s">"Vendor 2 only shipping"</span>
            },
            <span class="k">"payment"</span>: {
                <span class="k">"amount"</span>: <span class="n">0</span>,
                <span class="k">"tax"</span>: <span class="n">0</span>,
                <span class="k">"tax_namekeys"</span>: [],
                <span class="k">"method"</span>: <span class="s">"paypalcheckout"</span>,
                <span class="k">"method_name"</span>: <span class="s">"PayPal Checkout Express Test"</span>
            }
        },
        <span class="k">"totals"</span>: {
            <span class="k">"total"</span>: <span class="n">311.92</span>,
            <span class="k">"discount"</span>: <span class="n">0</span>,
            <span class="k">"shipping"</span>: <span class="n">4.9</span>,
            <span class="k">"payment"</span>: <span class="n">0</span>,
            <span class="k">"tax"</span>: <span class="n">0</span>
        }
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## An address of an order, with its form

GET /orders/**{id}**/address/**{type}** read since 6.6.0

The billing or shipping address of an order, together with the form the shop would use to edit it.

The form is sent with the values because a shop decides its own address fields: which exist, which are required, and in what order. Build the form from `fields` rather than assuming a shape, and `PUT` the same keys back.

### Path

ParameterTypeDescription

idrequiredintegerThe order id.

typerequiredstring&#96;billing&#96; or &#96;shipping&#96;.

### Response expand all

FieldTypeDescription

typestringWhich address this is.

address\_idintegerThe address row, `0` when the order has none of that kind.

fieldsobject\[\]The shop's address fields, in display order.namekeystringThe key to send the value back under.

typestringWhat to render: `text`, `zone`, `singledropdown`, and the rest.

raw\_typestringHikaShop's own name for the type.

labelstringTranslated into the operator's language.

defaultstringThe value used when none is given.

requiredbooleanWhether the shop refuses to save the address without it.

optionsobject\[\]The choices, for a field that has them. A country or a state is filled from the zones rather than from here.valuestringWhat to send back when this choice is picked.

labelstringWhat to show.

label\_keystringThe translation key behind the label, when there is one.

multiplebooleanWhether more than one may be chosen.

translatablebooleanNot meaningful on an address, where values are the customer's own words.

upload\_dirstringUnused on an address field.

allowed\_extensionsstringUnused on an address field.

date\_formatstringFor a date field, the format it is stored in.

valuesobjectThe current values, keyed by field namekey. Keyed by whatever address fields this shop has.

country\_namestringThe country spelled out, since the value itself is a zone id.

state\_namestringThe state spelled out, empty where the country has none.

### Errors

CodeHTTPMeans

not\_found404No such order, or the operator may not see it.

```
curl "$SHOP/hikashop-api/v1/orders/{id}/address/billing" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"type"</span>: <span class="s">"billing"</span>,
        <span class="k">"address_id"</span>: <span class="n">19</span>,
        <span class="k">"fields"</span>: [
            {
                <span class="k">"namekey"</span>: <span class="s">"address_title"</span>,
                <span class="k">"type"</span>: <span class="s">"singledropdown"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"singledropdown"</span>,
                <span class="k">"label"</span>: <span class="s">"Title"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">true</span>,
                <span class="k">"options"</span>: [
                    {
                        <span class="k">"value"</span>: <span class="s">"Mr"</span>,
                        <span class="k">"label"</span>: <span class="s">"Mr"</span>,
                        <span class="k">"label_key"</span>: <span class="s">"HIKA_TITLE_MR"</span>
                    },
                    {
                        <span class="k">"value"</span>: <span class="s">"Mrs"</span>,
                        <span class="k">"label"</span>: <span class="s">"Mrs"</span>,
                        <span class="k">"label_key"</span>: <span class="s">"HIKA_TITLE_MRS"</span>
                    },
                    {
                        <span class="k">"value"</span>: <span class="s">"Miss"</span>,
                        <span class="k">"label"</span>: <span class="s">"Miss"</span>,
                        <span class="k">"label_key"</span>: <span class="s">"HIKA_TITLE_MISS"</span>
                    },
                    {
                        <span class="k">"value"</span>: <span class="s">"Ms"</span>,
                        <span class="k">"label"</span>: <span class="s">"Ms"</span>,
                        <span class="k">"label_key"</span>: <span class="s">"HIKA_TITLE_MS"</span>
                    },
                    "… 1 more, trimmed for the example"
                ],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            },
            {
                <span class="k">"namekey"</span>: <span class="s">"address_firstname"</span>,
                <span class="k">"type"</span>: <span class="s">"text"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"text"</span>,
                <span class="k">"label"</span>: <span class="s">"First name"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">true</span>,
                <span class="k">"options"</span>: [],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            },
            {
                <span class="k">"namekey"</span>: <span class="s">"address_lastname"</span>,
                <span class="k">"type"</span>: <span class="s">"text"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"text"</span>,
                <span class="k">"label"</span>: <span class="s">"Last name"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">true</span>,
                <span class="k">"options"</span>: [],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            },
            {
                <span class="k">"namekey"</span>: <span class="s">"address_company"</span>,
                <span class="k">"type"</span>: <span class="s">"text"</span>,
                <span class="k">"raw_type"</span>: <span class="s">"text"</span>,
                <span class="k">"label"</span>: <span class="s">"Company"</span>,
                <span class="k">"default"</span>: <span class="s">""</span>,
                <span class="k">"required"</span>: <span class="n">false</span>,
                <span class="k">"options"</span>: [],
                <span class="k">"multiple"</span>: <span class="n">false</span>,
                <span class="k">"translatable"</span>: <span class="n">false</span>,
                <span class="k">"upload_dir"</span>: <span class="s">""</span>,
                <span class="k">"allowed_extensions"</span>: <span class="s">""</span>,
                <span class="k">"date_format"</span>: <span class="s">""</span>
            },
            "… 7 more, trimmed for the example"
        ],
        <span class="k">"values"</span>: {
            <span class="k">"address_title"</span>: <span class="s">"Mr"</span>,
            <span class="k">"address_firstname"</span>: <span class="s">"Alex"</span>,
            <span class="k">"address_lastname"</span>: <span class="s">"Marchand"</span>,
            <span class="k">"address_company"</span>: <span class="s">"Lilas SARL"</span>,
            <span class="k">"address_street"</span>: <span class="s">"12 rue des Lilas"</span>,
            <span class="k">"address_post_code"</span>: <span class="s">"44000"</span>,
            <span class="k">"address_city"</span>: <span class="s">"Nantes"</span>,
            <span class="k">"address_telephone"</span>: <span class="s">"+33 2 00 00 00 00"</span>,
            <span class="k">"address_country"</span>: <span class="s">""</span>,
            <span class="k">"address_state"</span>: <span class="s">""</span>,
            <span class="k">"address_vat"</span>: <span class="s">"FR00000000000"</span>
        },
        <span class="k">"country_name"</span>: <span class="s">""</span>,
        <span class="k">"state_name"</span>: <span class="s">""</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## The coupons that can be applied

GET /coupons read since 6.6.0

The shop's published coupons, so an operator can pick one rather than remember a code. Applying it is a separate call, and the shop validates it again there: a coupon listed here can still be refused for this particular order.

### Response a list expand all

FieldTypeDescription

idinteger

codestringWhat the customer would type. This is what you send to apply it.

flat\_amountnumberA fixed reduction, `0` when the coupon is a percentage.

percent\_amountnumberA percentage reduction, `0` when the coupon is a fixed amount.

currency\_idintegerThe currency a flat amount is expressed in.

startinteger\|nullUnix timestamp before which it is not valid.

endinteger\|nullUnix timestamp after which it expires.

quotaintegerHow many times it may be used in total, `0` for no limit.

used\_timesintegerHow many times it already has been.

minimum\_ordernumberThe order total below which it does not apply, `0` for none.

```
curl "$SHOP/hikashop-api/v1/coupons" \
  -H "Authorization: Bearer $TOKEN"
```

```
{
    <span class="k">"data"</span>: [
        {
            <span class="k">"id"</span>: <span class="n">1</span>,
            <span class="k">"code"</span>: <span class="s">"APPTEST10"</span>,
            <span class="k">"flat_amount"</span>: <span class="n">10</span>,
            <span class="k">"percent_amount"</span>: <span class="n">0</span>,
            <span class="k">"currency_id"</span>: <span class="n">1</span>,
            <span class="k">"start"</span>: <span class="n">0</span>,
            <span class="k">"end"</span>: <span class="n">0</span>,
            <span class="k">"quota"</span>: <span class="n">0</span>,
            <span class="k">"used_times"</span>: <span class="n">0</span>,
            <span class="k">"minimum_order"</span>: <span class="n">0</span>
        },
        {
            <span class="k">"id"</span>: <span class="n">2</span>,
            <span class="k">"code"</span>: <span class="s">"APPTEST20PCT"</span>,
            <span class="k">"flat_amount"</span>: <span class="n">0</span>,
            <span class="k">"percent_amount"</span>: <span class="n">20</span>,
            <span class="k">"currency_id"</span>: <span class="n">1</span>,
            <span class="k">"start"</span>: <span class="n">0</span>,
            <span class="k">"end"</span>: <span class="n">0</span>,
            <span class="k">"quota"</span>: <span class="n">0</span>,
            <span class="k">"used_times"</span>: <span class="n">0</span>,
            <span class="k">"minimum_order"</span>: <span class="n">0</span>
        },
        {
            <span class="k">"id"</span>: <span class="n">432</span>,
            <span class="k">"code"</span>: <span class="s">"E2E1786215715618"</span>,
            <span class="k">"flat_amount"</span>: <span class="n">0</span>,
            <span class="k">"percent_amount"</span>: <span class="n">12</span>,
            <span class="k">"currency_id"</span>: <span class="n">0</span>,
            <span class="k">"start"</span>: <span class="n">0</span>,
            <span class="k">"end"</span>: <span class="n">0</span>,
            <span class="k">"quota"</span>: <span class="n">0</span>,
            <span class="k">"used_times"</span>: <span class="n">0</span>,
            <span class="k">"minimum_order"</span>: <span class="n">0</span>
        },
        {
            <span class="k">"id"</span>: <span class="n">434</span>,
            <span class="k">"code"</span>: <span class="s">"E2E1786215747620"</span>,
            <span class="k">"flat_amount"</span>: <span class="n">0</span>,
            <span class="k">"percent_amount"</span>: <span class="n">12</span>,
            <span class="k">"currency_id"</span>: <span class="n">0</span>,
            <span class="k">"start"</span>: <span class="n">0</span>,
            <span class="k">"end"</span>: <span class="n">0</span>,
            <span class="k">"quota"</span>: <span class="n">0</span>,
            <span class="k">"used_times"</span>: <span class="n">0</span>,
            <span class="k">"minimum_order"</span>: <span class="n">0</span>
        }
    ],
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```

## Change an order's status

POST /orders/**{id}**/status write since 6.6.0

Moves the order and, when asked, sends the customer the same notification the backend would have sent.

This calls the same code the backend does, so stock, invoices and every plugin listening on a status change behave exactly as they do there. It is not a database update.

### Path

ParameterTypeDescription

idrequiredintegerThe order id.

### Body

FieldTypeDescription

statusrequiredstringA status \*\*namekey\*\*, as listed by `GET /statuses`. Not the translated label.

notifybooleanSend the customer the notification for the new status. Defaults to `false`.

reasonstringRecorded in the order history, and included in the notification when there is one.

### Response expand all

FieldTypeDescription

idintegerThe order id.

statusstringThe namekey the order now has.

changedbooleanFalse when the order already had that status.

notifiedbooleanWhether the customer was actually emailed, which can be false even when you asked, if the status has no notification configured.

### Errors

CodeHTTPMeans

invalid\_status400No such status namekey on this shop.

not\_found404No such order, or the operator may not see it.

save\_failed500The order could not be saved.

```
curl -X POST "$SHOP/hikashop-api/v1/orders/{id}/status" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "confirmed",
    "notify": false,
    "reason": "Documentation capture"
}'
```

```
{
    <span class="k">"data"</span>: {
        <span class="k">"id"</span>: <span class="n">5626</span>,
        <span class="k">"status"</span>: <span class="s">"confirmed"</span>,
        <span class="k">"changed"</span>: <span class="n">true</span>,
        <span class="k">"notified"</span>: <span class="n">false</span>
    },
    <span class="k">"meta"</span>: <span class="n">null</span>,
    <span class="k">"error"</span>: <span class="n">null</span>
}
```
