# Site Settings

https://dev.wisecp.com/es/site-settings

The six endpoints behind the company details, the site systems and the search engine details.

## Overview

These six endpoints hold the settings that describe the installation **itself**: who the company is, how to reach it, which systems are on, and what the site tells search engines.

All three pairs work the same way: one endpoint reads every setting, the other applies the fields you send and leaves the rest alone. But **the shape changes in three places**, and those are this article's pitfalls.

## Reference

### Reading the Basic Settings

get/api/v1/admin/settings/basic

`Settings/GetBasicSettings` admin company per language

Returns the company details, the contact channels and the contact form settings.

Response fields data — 8

companyobject 3 fieldsThe company details, keyed by language.

company_namestringThe company name.

addressstringThe company address.

informationsstringExtra information text.

email_addressesstring[]The contact e-mail addresses. The list is written whole.

phone_numbersstring[]The contact phone numbers. The list is written whole.

social_linksobject[] 3 fieldsThe social media links. The list is written whole.

iconstringThe icon class.

namestringThe link name.

urlstringThe link address.

map_embed_codestringThe embed code for the map on the contact page.

contact_formintWhether the contact form is on.

contact_form_mandatory_phoneintWhether the phone is required on the form.

contact_mapintWhether the map is shown.

Errors 1

insufficient_scope403The key lacks the required scope.

Request cURL JavaScript PHP (HTTP) PHP (Internal)

```bash
curl 'https://panel.example.com/api/v1/admin/settings/basic' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const res  = await fetch('https://panel.example.com/api/v1/admin/settings/basic', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
```

```php
$ch = curl_init('https://panel.example.com/api/v1/admin/settings/basic');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// The company details are kept PER LANGUAGE: each carries its own name and address.
$basic = Api::Settings()->GetBasicSettings()['data'];
$name  = $basic['company']['en']['company_name'];
```

Response 200

```json
{
  "data": {
    "company": {
      "en": {
        "company_name": "Example Inc.",
        "address": "123 Market Street",
        "informations": ""
      }
    },
    "email_addresses": ["support@example.com"],
    "phone_numbers": ["+1 555 0100"],
    "social_links": [
      { "icon": "fa-x", "name": "X", "url": "https://x.com/example" }
    ],
    "map_embed_code": "",
    "contact_form": 1,
    "contact_form_mandatory_phone": 0,
    "contact_map": 1
  }
}
```

### Writing the Basic Settings

put/api/v1/admin/settings/basic

`Settings/UpdateBasicSettings` admin lists are written whole

Applies the fields you send. The list fields are replaced, not merged.

Body 8

companyobject 3 fieldsThe company details, keyed by language.

company_namestringThe company name.

addressstringThe company address.

informationsstringExtra information text.

email_addressesstring[]The contact e-mail addresses. The list is written whole.

phone_numbersstring[]The contact phone numbers. The list is written whole.

social_linksobject[] 3 fieldsThe social media links. The list is written whole.

iconstringThe icon class.

namestringThe link name.

urlstringThe link address.

map_embed_codestringThe embed code for the map on the contact page.

contact_formintWhether the contact form is on.

contact_form_mandatory_phoneintWhether the phone is required on the form.

contact_mapintWhether the map is shown.

Response fields data — 8

dataobjectThe settings as they now stand. Same shape as the read endpoint.

Errors 1

insufficient_scope403The key lacks the required scope.

Request cURL JavaScript PHP (HTTP) PHP (Internal)

```bash
curl -X PUT 'https://panel.example.com/api/v1/admin/settings/basic' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"company":{"en":{"company_name":"Example Inc.","address":"123 Market Street","informations":""}},"email_addresses":["support@example.com"],"contact_form":1}'
```

```javascript
const res = await fetch('https://panel.example.com/api/v1/admin/settings/basic', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    company: {
      en: {
        company_name: 'Example Inc.',
        address: '123 Market Street',
        informations: '',
      },
    },
    contact_form: 1,
  }),
});

const body = await res.json();
```

```php
$ch = curl_init('https://panel.example.com/api/v1/admin/settings/basic');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'company'      => ['en' => ['company_name' => 'Example Inc.']],
        'contact_form' => 1,
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// To ADD one address send the existing list too: the list is written whole.
$basic  = Api::Settings()->GetBasicSettings()['data'];
$emails = $basic['email_addresses'];

$emails[] = 'sales@example.com';

Api::Settings()->UpdateBasicSettings(['email_addresses' => $emails]);
```

### Reading the Advanced Settings

get/api/v1/admin/settings/advanced

`Settings/GetAdvancedSettings` admin

Returns the settings for the basket, orders, support, limits, cache and embedded codes.

Response fields data — 26

basket_systemintWhether the basket system is on.

visitors_will_see_basketintWhether visitors who are not signed in see the basket.

easy_orderintWhether the quick order flow is on.

order_renewal_typestringHow order renewal works.

ticket_systemintWhether the support ticket system is on.

kbase_systemintWhether the knowledge base is on.

use_couponintWhether coupons can be used.

clear_end_two_zero_moneyintWhether trailing zeroes are hidden on prices.

ctoc_service_transferintWhether clients can hand services to each other.

voice_notificationintWhether the audible notification is on.

accessibilityintWhether the accessibility aids are on.

pagination_ranksintHow many rows a page of a list holds.

redirect_httpsintWhether visitors are redirected to the encrypted address.

redirect_wwwintWhether visitors are redirected to the prefixed address.

cookie_policyobjectThe cookie policy: its status and the page attached.

pg_activationobjectWhich payment methods are on. Only keys that already exist are updated.

limitsobjectThe system limits, a map from key to number.

product_fields_extensionsstringThe file extensions allowed on product fields.

attachment_extensionsstringThe file extensions allowed on attachments.

product_fields_max_file_sizeintThe maximum size for a product field file. Bytes when read, megabytes when written.

attachment_max_file_sizeintThe maximum size for an attachment. Bytes when read, megabytes when written.

cacheintWhether the cache is on.

analytics_codestringThe analytics code.

support_codestringThe support tool code.

webmaster_tools_codestringThe search engine verification code.

external_embed_codestringExternal code added to the pages.

Errors 1

insufficient_scope403The key lacks the required scope.

Request cURL JavaScript PHP (HTTP) PHP (Internal)

```bash
curl 'https://panel.example.com/api/v1/admin/settings/advanced' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const res  = await fetch('https://panel.example.com/api/v1/admin/settings/advanced', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
```

```php
$ch = curl_init('https://panel.example.com/api/v1/admin/settings/advanced');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// File sizes come back in BYTES but are written in megabytes; convert the unit.
$adv = Api::Settings()->GetAdvancedSettings()['data'];
$mb  = (int) round($adv['attachment_max_file_size'] / 1048576);
```

### Writing the Advanced Settings

put/api/v1/admin/settings/advanced

`Settings/UpdateAdvancedSettings` admin the size unit changes

Applies the fields you send and leaves the rest as they are.

Body 26

basket_systemintWhether the basket system is on.

visitors_will_see_basketintWhether visitors who are not signed in see the basket.

easy_orderintWhether the quick order flow is on.

order_renewal_typestringHow order renewal works.

ticket_systemintWhether the support ticket system is on.

kbase_systemintWhether the knowledge base is on.

use_couponintWhether coupons can be used.

clear_end_two_zero_moneyintWhether trailing zeroes are hidden on prices.

ctoc_service_transferintWhether clients can hand services to each other.

voice_notificationintWhether the audible notification is on.

accessibilityintWhether the accessibility aids are on.

pagination_ranksintHow many rows a page of a list holds.

redirect_httpsintWhether visitors are redirected to the encrypted address.

redirect_wwwintWhether visitors are redirected to the prefixed address.

cookie_policyobjectThe cookie policy: its status and the page attached.

pg_activationobjectWhich payment methods are on. Only keys that already exist are updated.

limitsobjectThe system limits, a map from key to number.

product_fields_extensionsstringThe file extensions allowed on product fields.

attachment_extensionsstringThe file extensions allowed on attachments.

product_fields_max_file_sizeintThe maximum size for a product field file. Bytes when read, megabytes when written.

attachment_max_file_sizeintThe maximum size for an attachment. Bytes when read, megabytes when written.

cacheintWhether the cache is on.

analytics_codestringThe analytics code.

support_codestringThe support tool code.

webmaster_tools_codestringThe search engine verification code.

external_embed_codestringExternal code added to the pages.

Response fields data — 26

dataobjectThe settings as they now stand. Same shape as the read endpoint, so the file sizes come back in bytes.

Errors 1

insufficient_scope403The key lacks the required scope.

Request cURL JavaScript PHP (HTTP) PHP (Internal)

```bash
curl -X PUT 'https://panel.example.com/api/v1/admin/settings/advanced' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"basket_system":1,"use_coupon":1,"cookie_policy":{"status":1,"page":0},"cache":1}'
```

```javascript
const res = await fetch('https://panel.example.com/api/v1/admin/settings/advanced', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    basket_system: 1,
    use_coupon: 1,
    cache: 1,
  }),
});

const body = await res.json();
```

```php
$ch = curl_init('https://panel.example.com/api/v1/admin/settings/advanced');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'basket_system' => 1,
        'use_coupon'    => 1,
        'cache'         => 1,
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// The size is written in MEGABYTES; do not send back the byte value you read.
Api::Settings()->UpdateAdvancedSettings([
    'attachment_max_file_size' => 10,
]);
```

### Reading the SEO Settings

get/api/v1/admin/settings/seo

`Settings/GetSeoSettings` admin per language

Returns what the home page tells search engines.

Response fields data

object 3 fieldsThe meta details, keyed by language.

titlestringThe page title.

keywordsstringThe keywords.

descriptionstringThe page description.

Errors 1

insufficient_scope403The key lacks the required scope.

Request cURL JavaScript PHP (HTTP) PHP (Internal)

```bash
curl 'https://panel.example.com/api/v1/admin/settings/seo' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const res  = await fetch('https://panel.example.com/api/v1/admin/settings/seo', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
```

```php
$ch = curl_init('https://panel.example.com/api/v1/admin/settings/seo');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// The response is keyed by language; the write is keyed by FIELD. The two shapes differ.
$seo = Api::Settings()->GetSeoSettings()['data'];
$en  = $seo['en']['title'];
```

### Writing the SEO Settings

put/api/v1/admin/settings/seo

`Settings/UpdateSeoSettings` admin the shape is inverted

Writes the home page meta details. The body is keyed by field, not by language.

Body 3

titleobjectThe titles, keyed by language.

keywordsobjectThe keywords, keyed by language.

descriptionobjectThe descriptions, keyed by language.

Response fields data

dataobjectThe settings as they now stand. Same shape as the read endpoint, so it comes back keyed by language, not by field.

Errors 1

insufficient_scope403The key lacks the required scope.

Request cURL JavaScript PHP (HTTP) PHP (Internal)

```bash
curl -X PUT 'https://panel.example.com/api/v1/admin/settings/seo' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"title":{"en":"Home"},"description":{"en":"Welcome."}}'
```

```javascript
const res = await fetch('https://panel.example.com/api/v1/admin/settings/seo', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    title: { en: 'Home' },
    description: { en: 'Welcome.' },
  }),
});

const body = await res.json();
```

```php
$ch = curl_init('https://panel.example.com/api/v1/admin/settings/seo');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'title'       => ['en' => 'Home'],
        'description' => ['en' => 'Welcome.'],
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```php
// Reading is keyed by language, writing by field: you have to invert the shape.
$seo = Api::Settings()->GetSeoSettings()['data'];

$titles = [];
foreach ($seo as $lang => $meta) $titles[$lang] = $meta['title'];
$titles['en'] = 'Home';

Api::Settings()->UpdateSeoSettings(['title' => $titles]);
```

## Pitfalls

> **The SEO read and write are keyed the other way**
> 
> The read returns objects grouped by language code; the write expects objects grouped by **field name**. Sending back what you read does not work, you have to invert the shape. The other two pairs have no such difference.

> **File sizes read in bytes and write in megabytes**
> 
> On the advanced settings the maximum file size fields come back in **bytes** but are written in **megabytes**. Sending the value you read straight back raises the limit a millionfold, and no error says a word about it.

> **List fields are not merged**
> 
> The contact e-mails, the phone numbers and the social links are **replaced** by the list you send. Adding one address means reading the current list and appending to it, or the rest are deleted.

> **The company details are per language**
> 
> The company name, the address and the extra information are kept separately for each language. Writing to one language leaves the others as they were, so on a multilingual site a visitor can see a different company name depending on their language.

> **New keys are not added to the payment list**
> 
> In the payment activation setting only keys that **already exist** are updated. Trying to switch on a method that is not installed is ignored without a word; the method has to be installed first.

## Related Articles

- [Client Registration](https://dev.wisecp.com/en/client-registration)
- [Localisation and URLs](https://dev.wisecp.com/en/localisation-and-urls)
- [Security Settings](https://dev.wisecp.com/en/security-settings)
