# Client Notes

https://dev.wisecp.com/es/client-internal-notes

The four endpoints that read, add, update and delete the internal notes attached to a client.

## Overview

A note is an **internal** line attached to the client record. The client never sees it on any screen; only operators working in the panel read it.

A note can be pinned. Pinned notes sit at the top of the list and the rest run newest to oldest.

## Reference

### Listing Notes

get/api/v1/admin/clients/{id}/notes

`Clients/GetClientNotes` admin

Returns the client's notes. The order is fixed: pinned first, then newest to oldest.

Response fields data[] — 6

idstringNote id. A string, not a number.

contentstringThe note text.

pinnedboolWhether the note is pinned.

added_byintId of the admin who added it.

added_by_namestringDisplay name of whoever added it.

created_atstringCreation time.

Errors 2

not_found404No such client or note.

insufficient_scope403The key lacks the required scope.

Request cURL JavaScript PHP (HTTP) PHP (Internal)

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

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

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

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

```php
$response = Api::Clients()->GetClientNotes(['id' => 42]);

foreach ($response['data'] as $note) {
    if ($note['pinned']) {
        $highlight[] = $note['content'];
    }
}
```

### Adding a Note

post/api/v1/admin/clients/{id}/notes

`Clients/CreateClientNote` admin

Adds a note to the client. The owner of the calling key is recorded as the author.

Body 2

contentstringrequiredThe note text.

pinnedboolPins the note to the top of the list. Defaults to `false`.

Response fields data

dataobjectThe note created, returned with `201`. Same shape as the list schema.

Errors 4

not_found404No such client.

content_required422The content is empty.

note_add_failed500The note could not be created.

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/clients/42/notes' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"content":"Clean payment history, priority client","pinned":true}'
```

```javascript
const res = await fetch('https://panel.example.com/api/v1/admin/clients/42/notes', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({"content":"Clean payment history, priority client","pinned":true}),
});

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

```php
$ch = curl_init('https://panel.example.com/api/v1/admin/clients/42/notes');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'content' => 'Clean payment history, priority client',
        'pinned'  => true,
    ]),
]);

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

```php
$response = Api::Clients()->CreateClientNote([
    'id'      => 42,
    'content' => 'Clean payment history, priority client',
    'pinned'  => true,
]);
```

### Updating a Note

patch/api/v1/admin/clients/{id}/notes/{note_id}

`Clients/UpdateClientNote` admin pinning lives here too

Changes the note text or its pinned state. You have to send at least one field.

Body at least one

contentstringThe new text. If sent, it cannot be empty.

pinnedboolPins or unpins the note.

Response fields data

dataobjectThe note after the update. Same shape as the list schema.

Errors 4

not_found404No such client or note.

content_required422The content was sent empty.

note_update_failed500The note could not be updated.

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/clients/42/notes/a1b2c3' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"pinned":false}'
```

```javascript
const res = await fetch('https://panel.example.com/api/v1/admin/clients/42/notes/a1b2c3', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ pinned: false }),
});

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

```php
$ch = curl_init('https://panel.example.com/api/v1/admin/clients/42/notes/a1b2c3');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PATCH',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode(['pinned' => false]),
]);

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

```php
// Unpinning goes through this endpoint too; there is no separate action.
$response = Api::Clients()->UpdateClientNote([
    'id'      => 42,
    'note_id' => 'a1b2c3',
    'pinned'  => false,
]);
```

### Deleting a Note

delete/api/v1/admin/clients/{id}/notes/{note_id}

`Clients/DeleteClientNote` admin

Deletes the note.

Response fields data

deletedboolWhether the delete succeeded.

idstringId of the deleted note.

Errors 3

not_found404No such client or note.

note_delete_failed500The note could not be deleted.

insufficient_scope403The key lacks the required scope.

Request cURL JavaScript PHP (HTTP) PHP (Internal)

```bash
curl -X DELETE 'https://panel.example.com/api/v1/admin/clients/42/notes/a1b2c3' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const res = await fetch('https://panel.example.com/api/v1/admin/clients/42/notes/a1b2c3', {
  method: 'DELETE',
  headers: { Authorization: `Bearer ${apiKey}` },
});

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

```php
$ch = curl_init('https://panel.example.com/api/v1/admin/clients/42/notes/a1b2c3');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'DELETE',
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

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

```php
$response = Api::Clients()->DeleteClientNote([
    'id'      => 42,
    'note_id' => 'a1b2c3',
]);
```

## Pitfalls

> **A note id is not a number**
> 
> Unlike the other resources, `id` here is a string (`a1b2c3`). Code that casts it to a number will not find the record.

> **There is no separate pin endpoint**
> 
> In the panel pinning looks like its own action; in the API `pinned` is a field like any other and goes through the update endpoint.

## Related Articles

- [Client Endpoints](https://dev.wisecp.com/en/client-endpoints)
- [Request and Response Format](https://dev.wisecp.com/en/request-and-response-format)
