---
title: "Update a reseller"
description: "PATCH-style update for a reseller's profile fields (username, email, member group, password, notes)."
---

# Update a reseller

Update a reseller's profile fields. The endpoint is PATCH-style: only the fields you include in the body change; every other column keeps its current value.

Credit and slot changes go through [`POST /resellers/{id}/billing/adjust`](/docs/?page=xai-ref-resellers-billing-adjust) so the adjustment can be atomic and audited. Re-parenting an account is a CMS-only operation because it needs the full-tree view to be safe. Everything else is here.

## Endpoint

`POST https://<your-panel-domain>/panel-api/v1/resellers/{id}/update`

## Authentication

Send the API key in the `Authorization: Bearer <your-api-key>` header. Only admin keys can call this endpoint.

## Required scope

`resellers:write`

## Idempotency

Every POST must include an `Idempotency-Key` header. Reusing the same key with the same body replays the cached response; reusing it with a different body returns `409 idempotency_conflict`. See the [Rate limits and Idempotency](/docs/?page=panel-api-rate-limits-idempotency) page.

## Path parameters

| Name | Type | Description |
| ---- | ---- | ----------- |
| `id` | int | The reg-user ID of the reseller to update. |

## Request body

Every field is optional. Send only the ones you want to change.

| Field | Type | Required | Default | Description |
| ----- | ---- | -------- | ------- | ----------- |
| `username` | string | no | current value | Login name. Same length and character rules as create. |
| `password` | string | no | keeps current | New login password. Send an empty string or omit the field to keep the current one. |
| `email` | string | no | current value | Validated with `FILTER_VALIDATE_EMAIL`. |
| `member_group_id` | int | no | current value | Move the account to a different member group. |
| `notes` | string | no | current value | Free-form label. |

The following columns are **preserved** by this endpoint and cannot be changed through it: `owner_id`, `credits`, `billing_mode`, `billing_expires`, `max_users`, `override_packages`, `default_lang`, `reseller_dns`, `pin_access`, `pin_code`, `badge_label`, `badge_color`.

```json
{
  "notes": "test"
}
```

## Response

The response is a compact summary of the account after the update. `billing` reflects the same snapshot as `GET /resellers/{id}/billing`.

```json
{
  "id": 262260,
  "username": "reseller_new",
  "email": "reseller_new@example.com",
  "member_group_id": 4,
  "billing": {
    "mode": "credits",
    "credits": 10,
    "max_users": null,
    "active_users": null,
    "billing_expires": null
  }
}
```

## Examples

### cURL

```bash
curl -X POST https://<your-panel-domain>/panel-api/v1/resellers/262260/update \
  -H "Authorization: Bearer <your-api-key>" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: crm-note-90142" \
  -d '{"notes":"test"}'
```

### PHP SDK

```php
require __DIR__ . '/api-panel-php-sdk-1.0.0/autoload.php';
use XtreamAI\PanelApi\PanelApiClient;

$client = new PanelApiClient(baseUrl: 'https://<your-panel-domain>', token: '<your-api-key>');
$reseller = $client->resellers->update(
    id: 262260,
    fields: ['notes' => 'test'],
    idempotencyKey: 'crm-note-90142',
);
echo $reseller->email, PHP_EOL;
```

### Python SDK

```python
from xtream_ai_panel_api import PanelApiClient

client = PanelApiClient(base_url="https://<your-panel-domain>", token="<your-api-key>")
reseller = client.resellers.update(
    262260,
    {"notes": "test"},
    idempotency_key="crm-note-90142",
)
print(reseller.email)
```

## Errors

| HTTP | Error slug | When it happens | How to fix |
| ---- | ---------- | --------------- | ---------- |
| 400 | `missing_idempotency_key` | The `Idempotency-Key` header was not sent. | Add the header on every POST. |
| 401 | `invalid_key` | Missing, malformed, or unknown API key. | Send a live key in `Authorization: Bearer <token>`. |
| 403 | `admin_only_endpoint` | A reseller key called this endpoint. | Use an admin key. |
| 403 | `insufficient_scope` | The key does not carry `resellers:write`. | Rotate the key with the correct scopes. |
| 404 | `not_found` | No reseller exists with that ID. | Verify the ID with `GET /resellers/{id}` first. |
| 409 | `idempotency_conflict` | The `Idempotency-Key` was reused with a different body. | Generate a new key or resend the original body. |
| 422 | `validation_error` | Username, password, email, or group fails validation. The message carries the reason. | Fix the offending field and resend. |
| 429 | `rate_limited` | The per-key request budget for this minute is spent. | Back off and retry after the minute rolls over. |

## See also

- [Get a reseller](/docs/?page=xai-ref-resellers-get)
- [Adjust reseller billing](/docs/?page=xai-ref-resellers-billing-adjust)
- [Panel API Resellers overview](/docs/?page=xai-ref-resellers-list)
