# Service Settings and Server

https://dev.wisecp.com/es/service-settings-and-server

The four endpoints behind a service's access details, limits, server and information blocks.

## Overview

These four endpoints touch a service's **settings**. The update on the service endpoints handles billing and dates; these decide how the service is reached, which server it sits on, and what the client reads on their page.

The management form behaves differently per service type: access details and limits are handled on hosting, server and special products, while licence fields apply to software services only. A field sent to the wrong type is ignored without a word.

## Reference

### Saving the Management Form

patch/api/v1/admin/services/{id}/management

`Services/UpdateServiceManagement` admin depends on the type

Saves a service's access details, resource limits and licence fields.

Body 8

accessobject 5 fieldsHow the service is reached. Only the fields you send change; the rest stay as they are.

domainstringThe domain tied to the service.

hostnamestringThe host name.

ipstringThe service address.

usernamestringThe sign-in username.

passwordstringThe sign-in password. Stored encrypted and never read back.

override_product_limitsboolOverrides the product's limits for this service. Limits you send without turning this on are not applied.

limitsobjectThe resource limits. The fields follow the service type: disk and bandwidth on hosting, processor, memory, disk and bandwidth on a server.

modulestringThe module running the service. On special products only.

licenseobject 4 fieldsThe licence fields. Handled on software services only.

domainstringThe domain the licence is locked to.

ipstringThe address the licence is locked to.

codestringThe licence key.

license_parametersobjectExtra fields the licence carries.

creation_infoobjectThe module's creation info. Merged into what is already there.

configobjectThe module settings. Merged into what is already there.

configurationobjectThe module configuration. Merged into what is already there.

Response fields data

dataobjectThe service as it now stands. Same shape as the detail endpoint in the service endpoints article.

——The password never comes back in the answer. Read `options` to confirm the access details that are not secret.

Errors 2

not_found404No such service.

insufficient_scope403The key lacks the required scope.

Request cURL JavaScript PHP (HTTP) PHP (Internal)

```bash
curl -X PATCH 'https://panel.example.com/api/v1/admin/services/506/management' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"access":{"username":"john"},"override_product_limits":true,"limits":{"disk_limit":50}}'
```

```javascript
const res = await fetch('https://panel.example.com/api/v1/admin/services/506/management', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    access: { username: 'john' },
    override_product_limits: true,
    limits: { disk_limit: 50 },
  }),
});

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

```php
$ch = curl_init('https://panel.example.com/api/v1/admin/services/506/management');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PATCH',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'access'                  => ['username' => 'john'],
        'override_product_limits' => true,
        'limits'                  => ['disk_limit' => 50],
    ]),
]);

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

```php
// Sending limits is not enough: turn the override on first, or the product's limits still rule.
$response = Api::Services()->UpdateServiceManagement([
    'id'                      => 506,
    'override_product_limits' => true,
    'limits'                  => ['disk_limit' => 50, 'bandwidth_limit' => 500],
]);
```

### Moving to Another Server

put/api/v1/admin/services/{id}/server

`Services/SetServiceServer` admin no data is moved

Points the service record at another server and updates the module to match.

Body 1

server_idintrequiredId of the target server. Sending zero leaves the service without a server and drops the module.

Response fields data — 3

server_idintId of the new server.

modulestringThe module the target server brings. `none` when left without a server.

idintService id.

Errors 4

not_found404No such service.

same_server422The service is already on that server.

server_not_found422The target server does not exist.

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/services/506/server' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"server_id":5}'
```

```javascript
const res = await fetch('https://panel.example.com/api/v1/admin/services/506/server', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ server_id: 5 }),
});

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

```php
$ch = curl_init('https://panel.example.com/api/v1/admin/services/506/server');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode(['server_id' => 5]),
]);

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

```php
// This endpoint moves the RECORD only; building the account on the new server is separate work.
$response = Api::Services()->SetServiceServer([
    'id'        => 506,
    'server_id' => 5,
]);

$module = $response['data']['module'];
```

Response 200 422

```json
{
  "data": {
    "server_id": 5,
    "module": "Mailcow",
    "id": 506
  }
}
```

```json
{
  "error": {
    "code": "same_server",
    "message": "Service is already on this server."
  }
}
```

### Writing the Information Blocks

put/api/v1/admin/services/{id}/blocks

`Services/SetServiceBlocks` admin the list is written whole

Writes the free-text blocks the client sees on the service page.

Body 1

blocksarrayrequiredThe list of blocks. Each carries a title and a description. A block empty in both is skipped, and a second name is accepted for the description field.

Response fields data — 2

blocksarrayThe blocks that were stored.

idintService id.

Errors 3

not_found404No such service.

invalid_blocks422`blocks` is not an array.

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/services/506/blocks' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"blocks":[{"title":"Connection","description":"Connect over SSH on port 22."}]}'
```

```javascript
const res = await fetch('https://panel.example.com/api/v1/admin/services/506/blocks', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    blocks: [
      { title: 'Connection', description: 'Connect over SSH on port 22.' },
    ],
  }),
});

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

```php
$ch = curl_init('https://panel.example.com/api/v1/admin/services/506/blocks');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'blocks' => [
            ['title' => 'Connection', 'description' => 'Connect over SSH on port 22.'],
        ],
    ]),
]);

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

```php
// To ADD a block send the existing list too: what you send becomes the truth.
$service = Api::Services()->GetService(['id' => 506])['data'];
$blocks  = $service['options']['blocks'] ?? [];

$blocks[] = ['title' => 'Backups', 'description' => 'Nightly, kept for 7 days.'];

Api::Services()->SetServiceBlocks(['id' => 506, 'blocks' => $blocks]);
```

### Clearing the Status Message

post/api/v1/admin/services/{id}/clear-status-message

`Services/ClearServiceStatusMessage` admin

Removes the sticky status message the module left behind.

Body —

——No body is needed. The service comes from the path and the whole message always goes; send an empty body.

Response fields data — 2

clearedboolWhether it was cleared.

idintService id.

Errors 2

not_found404No such service.

insufficient_scope403The key lacks the required scope.

Request cURL JavaScript PHP (HTTP) PHP (Internal)

```bash
curl -X POST 'https://panel.example.com/api/v1/admin/services/506/clear-status-message' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const res = await fetch('https://panel.example.com/api/v1/admin/services/506/clear-status-message', {
  method: 'POST',
  headers: { Authorization: `Bearer ${apiKey}` },
});

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

```php
$ch = curl_init('https://panel.example.com/api/v1/admin/services/506/clear-status-message');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

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

```php
// Clearing the message does not fix its cause: the module can write the same error again.
$response = Api::Services()->ClearServiceStatusMessage(['id' => 506]);
```

## Pitfalls

> **Changing the server does not move the data**
> 
> This endpoint only points the **record** at the new server and swaps the module to match. The account stays exactly where it was on the old server and is never created on the new one. The real migration is separate work; this call is for lining the record up afterwards.

> **Limits do nothing until the flag is on**
> 
> Sending resource limits is not enough on its own: with `override_product_limits` off the product's limits still rule and your values are not applied. No error is raised either, so read the service detail back to confirm.

> **The block list is written whole**
> 
> What you send becomes the truth: blocks missing from the list are deleted. To add one, read the current list first, append to it and send all of it back. A block empty in both title and description is skipped without a word.

> **Clearing the message does not fix its cause**
> 
> The status message is a trace the module left. Clearing it removes the text only; if the same error persists the module writes it again on its next operation. Look at why it was written before hiding it.

## Related Articles

- [Service Endpoints](https://dev.wisecp.com/en/service-endpoints)
- [Service Lifecycle](https://dev.wisecp.com/en/service-lifecycle)
- [Provisioning Servers](https://dev.wisecp.com/en/provisioning-servers)
