API x333e3
Управляйте серверами, оформляйте заказы и получайте историю расходов из своих приложений.
https://x333e3.xyz/api/v1POST принимает JSON-объект.
1100 означает 11.00 USD.
Сервера доступны по публичному хэшу.
Авторизация
Создайте токен в разделе «Настройки → API и webhooks». Выберите необходимые права и срок действия. Передавайте токен в заголовке — не в URL.
export X333_TOKEN='YOUR_API_TOKEN'
curl https://x333e3.xyz/api/v1/servers \
-H "Authorization: Bearer $X333_TOKEN"Токен участника ограничен его рабочим пространством, правами и списком серверов. Отзыв токена, доступа участника или смена данных входа прекращают доступ. Секрет показывается один раз при создании.
servers:readКонфигурации и сервераservers:powerУправление питаниемservers:renewПродлениеorders:writeКорзина и заказыoperations:readСтатусы операцийbilling:readИстория расходовБезопасные повторы
Каждый POST требует Idempotency-Key: от 16 до 100 букв, цифр и символов _ : -. Для новой операции создавайте новый ключ; при сетевом сбое повторяйте прежний ключ и то же тело запроса.
- Сохраните ключ до отправки команды.
- Если ответ не получен, повторите запрос с тем же ключом.
- Если ответ содержит
operation_id, проверьте результат черезGET /operations.
operation_id принята в очередь; это ещё не означает её завершение. Повтор с другими параметрами и прежним ключом возвращает конфликт 409.Ошибки и ограничения
{
"error": {
"message": "Токен недоступен или не имеет нужного права.",
"code": 403
}
}| Код | Значение |
|---|---|
400 | Неверные параметры или JSON |
401 | Отсутствует заголовок авторизации |
403 | Токен, права или доступ недоступны |
404 | Ресурс или маршрут не найден |
409 | Конфликт, занятая операция или нет наличия |
413 | Тело запроса превышает 32 КБ |
415 | Нужен Content-Type: application/json |
429 | Превышена частота запросов |
503 | Временная ошибка |
Прикладной лимит: 180 запросов на токен и 360 на аккаунт за 15-минутное окно. Защита WAF действует дополнительно; API-токен не отменяет её правила.
Максимумы ответов: 500 серверов, 100 операций и 5000 строк расходов. В корзине до 10 позиций; количество одной позиции — 1–10. Тело POST — до 32 КБ.
Webhooks
Настройте HTTPS endpoint и подписки в кабинете. Допускается порт 443 без редиректов. Локальные и закрытые адреса запрещены. Пароли и реквизиты серверов в payload не входят.
Проверка подписи
Подписана строка timestamp + '.' + исходные байты JSON. Допуск времени — 5 минут. Проверяйте HMAC до разбора и обработки события.
X-X333-Event: server.operation
X-X333-Delivery: DELIVERY_ID
X-X333-Timestamp: UNIX_TIMESTAMP
X-X333-Signature: v1=HEX_HMAC_SHA256import hashlib, hmac, time
def verify(raw_body: bytes, headers, secret: str) -> bool:
timestamp = headers.get('X-X333-Timestamp', '')
try:
if abs(time.time() - int(timestamp)) > 300:
return False
except (ValueError, TypeError):
return False
message = timestamp.encode() + b'.' + raw_body
expected = 'v1=' + hmac.new(
secret.encode(), message, hashlib.sha256
).hexdigest()
return hmac.compare_digest(
expected, headers.get('X-X333-Signature', '')
)Доставка может повторяться: сохраните X-X333-Delivery с UNIQUE-ограничением. Возвращайте 2xx после надёжного сохранения события. Максимум 8 попыток с возрастающей задержкой; журнал и ручной повтор — в кабинете.
События
server.readyserver.operationorder.createdbilling.creditbilling.renewalbilling.reminderticket.replyticket.openedstock.availableteam.changedmaintenance.plannedmaintenance.emergencyresource.warningresource.recoveryendpoint.test/plansТарифы и наличие
Актуальные конфигурации, цены в центах и число доступных серверов по локациям.
servers:readДополнительных параметров нет.
Ответ 200
Пример структуры, не реальные данные.
{
"data": [
{
"id": 1,
"name": "Nano",
"cpu": 4,
"ram_gb": 8,
"disk_gb": 100,
"price_cents": 1100,
"locations": [
{
"code": "nl",
"label": "Нидерланды",
"available": 2
}
]
}
]
}curl 'https://x333e3.xyz/api/v1/plans' \
-H "Authorization: Bearer $X333_TOKEN"const response = await fetch('https://x333e3.xyz/api/v1/plans', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.X333_TOKEN}`
}
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.message);
console.log(result);import os
import requests
response = requests.get(
'https://x333e3.xyz/api/v1/plans',
headers={
'Authorization': f"Bearer {os.environ['X333_TOKEN']}"
},
timeout=20,
)
response.raise_for_status()
print(response.json())/serversСписок серверов
Сервера рабочего пространства токена. Учитываются права участника и список доступных ему серверов.
servers:readДополнительных параметров нет.
Ответ 200
Пример структуры, не реальные данные.
{
"data": [
{
"id": "0123456789abcdef0123456789abcdef",
"name": "web-01",
"state": "provisioned",
"ip": "192.0.2.10",
"configuration": "4 vCPU / 8 GB RAM / 100 GB NVMe",
"location": "Нидерланды",
"os": "Ubuntu 24.04",
"renewal_price_cents": 1100,
"paid_until": 1795000000,
"auto_renew": true
}
]
}curl 'https://x333e3.xyz/api/v1/servers' \
-H "Authorization: Bearer $X333_TOKEN"const response = await fetch('https://x333e3.xyz/api/v1/servers', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.X333_TOKEN}`
}
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.message);
console.log(result);import os
import requests
response = requests.get(
'https://x333e3.xyz/api/v1/servers',
headers={
'Authorization': f"Bearer {os.environ['X333_TOKEN']}"
},
timeout=20,
)
response.raise_for_status()
print(response.json())/servers/{hash}Данные сервера
Конфигурация, адрес, состояние, срок оплаты и автопродление. Пароли и реквизиты в ответ не входят.
servers:readПараметры
hashstring · pathПубличный идентификатор сервера: 32 шестнадцатеричных символа. Возьмите из GET /servers.
Ответ 200
Пример структуры, не реальные данные.
{
"data": {
"id": "0123456789abcdef0123456789abcdef",
"name": "web-01",
"state": "provisioned",
"ip": "192.0.2.10",
"configuration": "4 vCPU / 8 GB RAM / 100 GB NVMe",
"location": "Нидерланды",
"os": "Ubuntu 24.04",
"renewal_price_cents": 1100,
"paid_until": 1795000000,
"auto_renew": true
}
}curl 'https://x333e3.xyz/api/v1/servers/0123456789abcdef0123456789abcdef' \
-H "Authorization: Bearer $X333_TOKEN"const response = await fetch('https://x333e3.xyz/api/v1/servers/0123456789abcdef0123456789abcdef', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.X333_TOKEN}`
}
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.message);
console.log(result);import os
import requests
response = requests.get(
'https://x333e3.xyz/api/v1/servers/0123456789abcdef0123456789abcdef',
headers={
'Authorization': f"Bearer {os.environ['X333_TOKEN']}"
},
timeout=20,
)
response.raise_for_status()
print(response.json())/operationsСостояние операций
До 100 последних операций. Сопоставьте id с operation_id принятой команды и проверяйте state.
operations:readДополнительных параметров нет.
Ответ 200
Пример структуры, не реальные данные.
{
"data": [
{
"id": 42,
"server": "0123456789abcdef0123456789abcdef",
"action": "restart",
"action_label": "Перезапуск",
"state": "queued",
"label": "В очереди",
"phase": "В очереди",
"created": "2026-10-26 10:00:00",
"updated": "2026-10-26 10:00:00",
"error": ""
}
]
}curl 'https://x333e3.xyz/api/v1/operations' \
-H "Authorization: Bearer $X333_TOKEN"const response = await fetch('https://x333e3.xyz/api/v1/operations', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.X333_TOKEN}`
}
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.message);
console.log(result);import os
import requests
response = requests.get(
'https://x333e3.xyz/api/v1/operations',
headers={
'Authorization': f"Bearer {os.environ['X333_TOKEN']}"
},
timeout=20,
)
response.raise_for_status()
print(response.json())/billingИстория расходов
До 5000 операций за выбранный месяц. amount_cents — целые центы USD: положительное значение означает пополнение, отрицательное — списание.
billing:readПараметры
monthstring · queryМесяц в формате YYYY-MM. По умолчанию — текущий месяц UTC.
Ответ 200
Пример структуры, не реальные данные.
{
"data": [
{
"id": 7,
"created": "2026-10-26 10:00:00",
"amount_cents": -1100,
"description": "Продление сервера",
"server": "0123456789abcdef0123456789abcdef",
"project": "Без проекта"
}
]
}curl 'https://x333e3.xyz/api/v1/billing?month=2026-10' \
-H "Authorization: Bearer $X333_TOKEN"const response = await fetch('https://x333e3.xyz/api/v1/billing?month=2026-10', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.X333_TOKEN}`
}
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.message);
console.log(result);import os
import requests
response = requests.get(
'https://x333e3.xyz/api/v1/billing?month=2026-10',
headers={
'Authorization': f"Bearer {os.environ['X333_TOKEN']}"
},
timeout=20,
)
response.raise_for_status()
print(response.json())/cartДобавить в корзину
Добавляет позицию или заменяет её количество для сочетания тарифа и локации. Само добавление не оформляет заказ.
orders:writeПараметры
plan_idinteger · bodyID активного тарифа из GET /plans.
locationstring · bodyКод доступной локации тарифа, например nl или us.
quantityinteger · bodyОт 1 до 10. По умолчанию 1.
project_idinteger · bodyНеобязательно: ID существующего проекта. По умолчанию 0 — без проекта.
Idempotency-Key.Ответ 201
Пример структуры, не реальные данные.
{
"data": {
"cart": [
{
"plan_id": 1,
"location": "nl",
"quantity": 1
}
]
}
}curl -X POST 'https://x333e3.xyz/api/v1/cart' \
-H "Authorization: Bearer $X333_TOKEN" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cart-request-20261026-001' \
-d '{"plan_id": 1, "location": "nl", "quantity": 1}'const response = await fetch('https://x333e3.xyz/api/v1/cart', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.X333_TOKEN}`,
'Content-Type': 'application/json',
'Idempotency-Key': 'cart-request-20261026-001'
},
body: JSON.stringify({"plan_id": 1, "location": "nl", "quantity": 1})
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.message);
console.log(result);import os
import requests
response = requests.post(
'https://x333e3.xyz/api/v1/cart',
headers={
'Authorization': f"Bearer {os.environ['X333_TOKEN']}",
'Idempotency-Key': 'cart-request-20261026-001'
},
json={'plan_id': 1, 'location': 'nl', 'quantity': 1},
timeout=20,
)
response.raise_for_status()
print(response.json())/checkoutОформить заказ
Оформляет всю корзину с баланса. Наличие и стоимость проверяются заново. При нехватке серверов корзина не списывается частично.
orders:writeТело запроса: пустой JSON-объект {}.
Idempotency-Key.Ответ 202
Пример структуры, не реальные данные.
{
"data": {
"kind": "checkout",
"servers": [
{
"server": "0123456789abcdef0123456789abcdef",
"operation_id": 42
}
],
"amount_cents": 1100
}
}curl -X POST 'https://x333e3.xyz/api/v1/checkout' \
-H "Authorization: Bearer $X333_TOKEN" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: checkout-request-20261026-001' \
-d '{}'const response = await fetch('https://x333e3.xyz/api/v1/checkout', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.X333_TOKEN}`,
'Content-Type': 'application/json',
'Idempotency-Key': 'checkout-request-20261026-001'
},
body: JSON.stringify({})
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.message);
console.log(result);import os
import requests
response = requests.post(
'https://x333e3.xyz/api/v1/checkout',
headers={
'Authorization': f"Bearer {os.environ['X333_TOKEN']}",
'Idempotency-Key': 'checkout-request-20261026-001'
},
json={},
timeout=20,
)
response.raise_for_status()
print(response.json())/servers/{hash}/startВключить сервер
Ставит включение сервера в очередь. Принятая команда ещё не означает завершённое включение.
servers:powerПараметры
hashstring · pathПубличный идентификатор сервера: 32 шестнадцатеричных символа. Возьмите из GET /servers.
Idempotency-Key.Ответ 202
Пример структуры, не реальные данные.
{
"data": {
"operation_id": 42,
"state": "queued"
}
}curl -X POST 'https://x333e3.xyz/api/v1/servers/0123456789abcdef0123456789abcdef/start' \
-H "Authorization: Bearer $X333_TOKEN" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: start-request-20261026-001' \
-d '{}'const response = await fetch('https://x333e3.xyz/api/v1/servers/0123456789abcdef0123456789abcdef/start', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.X333_TOKEN}`,
'Content-Type': 'application/json',
'Idempotency-Key': 'start-request-20261026-001'
},
body: JSON.stringify({})
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.message);
console.log(result);import os
import requests
response = requests.post(
'https://x333e3.xyz/api/v1/servers/0123456789abcdef0123456789abcdef/start',
headers={
'Authorization': f"Bearer {os.environ['X333_TOKEN']}",
'Idempotency-Key': 'start-request-20261026-001'
},
json={},
timeout=20,
)
response.raise_for_status()
print(response.json())/servers/{hash}/stopВыключить сервер
Ставит выключение в очередь. Команда влияет на работу реального сервера.
servers:powerПараметры
hashstring · pathПубличный идентификатор сервера: 32 шестнадцатеричных символа. Возьмите из GET /servers.
Idempotency-Key.Ответ 202
Пример структуры, не реальные данные.
{
"data": {
"operation_id": 42,
"state": "queued"
}
}curl -X POST 'https://x333e3.xyz/api/v1/servers/0123456789abcdef0123456789abcdef/stop' \
-H "Authorization: Bearer $X333_TOKEN" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: stop-request-20261026-001' \
-d '{}'const response = await fetch('https://x333e3.xyz/api/v1/servers/0123456789abcdef0123456789abcdef/stop', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.X333_TOKEN}`,
'Content-Type': 'application/json',
'Idempotency-Key': 'stop-request-20261026-001'
},
body: JSON.stringify({})
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.message);
console.log(result);import os
import requests
response = requests.post(
'https://x333e3.xyz/api/v1/servers/0123456789abcdef0123456789abcdef/stop',
headers={
'Authorization': f"Bearer {os.environ['X333_TOKEN']}",
'Idempotency-Key': 'stop-request-20261026-001'
},
json={},
timeout=20,
)
response.raise_for_status()
print(response.json())/servers/{hash}/restartПерезапустить сервер
Ставит перезапуск в очередь. Отслеживайте результат через GET /operations.
servers:powerПараметры
hashstring · pathПубличный идентификатор сервера: 32 шестнадцатеричных символа. Возьмите из GET /servers.
Idempotency-Key.Ответ 202
Пример структуры, не реальные данные.
{
"data": {
"operation_id": 42,
"state": "queued"
}
}curl -X POST 'https://x333e3.xyz/api/v1/servers/0123456789abcdef0123456789abcdef/restart' \
-H "Authorization: Bearer $X333_TOKEN" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: restart-request-20261026-001' \
-d '{}'const response = await fetch('https://x333e3.xyz/api/v1/servers/0123456789abcdef0123456789abcdef/restart', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.X333_TOKEN}`,
'Content-Type': 'application/json',
'Idempotency-Key': 'restart-request-20261026-001'
},
body: JSON.stringify({})
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.message);
console.log(result);import os
import requests
response = requests.post(
'https://x333e3.xyz/api/v1/servers/0123456789abcdef0123456789abcdef/restart',
headers={
'Authorization': f"Bearer {os.environ['X333_TOKEN']}",
'Idempotency-Key': 'restart-request-20261026-001'
},
json={},
timeout=20,
)
response.raise_for_status()
print(response.json())/servers/{hash}/renewПродлить на 30 дней
Продлевает сервер с баланса рабочего пространства. Возвращает новый срок оплаты и списанную сумму в центах. Продление выполняется сразу; отдельная операция в очереди не создаётся.
servers:renewПараметры
hashstring · pathПубличный идентификатор сервера: 32 шестнадцатеричных символа. Возьмите из GET /servers.
Idempotency-Key.Ответ 202
Пример структуры, не реальные данные.
{
"data": {
"paid_until": 1797592000,
"amount_cents": 1100
}
}curl -X POST 'https://x333e3.xyz/api/v1/servers/0123456789abcdef0123456789abcdef/renew' \
-H "Authorization: Bearer $X333_TOKEN" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: renew-request-20261026-001' \
-d '{}'const response = await fetch('https://x333e3.xyz/api/v1/servers/0123456789abcdef0123456789abcdef/renew', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.X333_TOKEN}`,
'Content-Type': 'application/json',
'Idempotency-Key': 'renew-request-20261026-001'
},
body: JSON.stringify({})
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.message);
console.log(result);import os
import requests
response = requests.post(
'https://x333e3.xyz/api/v1/servers/0123456789abcdef0123456789abcdef/renew',
headers={
'Authorization': f"Bearer {os.environ['X333_TOKEN']}",
'Idempotency-Key': 'renew-request-20261026-001'
},
json={},
timeout=20,
)
response.raise_for_status()
print(response.json())