
Manage your services, servers, invoices and tickets from your own software.
Zenix API
The Zenix API is a JSON REST API over HTTPS. Every request is authenticated with an API key that the account owner creates in the customer panel. The API never exposes payment, ordering or account-security actions.
OpenAPI 3.1 specification (openapi.json)
The complete reference: every endpoint with its parameters, request bodies, response schemas, required scope, examples and error codes, in one machine-readable file. Import it into Postman, Insomnia or Swagger Editor, or generate a client library with openapi-generator.
https://api.zenix.net.tr/v1/openapi.jsonBase URL
https://api.zenix.net.tr/v1
All endpoints are relative to this address. Plain HTTP is rejected.
Authentication
The account owner creates keys in the customer panel under API keys, confirming with their password and two-factor code. The key is shown once; store it like a password and send it on every request:
Authorization: Bearer zxc_live_...
Never put the key in a URL. Requests without a valid key get 401; repeated failures from one address are rate limited. The account owner is emailed when a key is created or revoked, and can revoke a key at any time.
Scopes
A key only works for the scopes it was created with. Scopes and services cannot be changed: to change them, revoke the key and create a new one. The allowed IP addresses can be edited in the customer panel at any time.
| Scope | Grants |
|---|---|
| services:read | List services and read service details, server overview and live server status. |
| servers:power | Start, stop, restart and power off servers. Requires services:read. |
| domains:read | List domains. Transfer (EPP) codes are never returned. |
| energy:read | Read energy consumption and live load (live load only for keys covering all services). |
| invoices:read | List and read invoices. Account-wide. |
| tickets:read | List and read support tickets. Account-wide. |
| tickets:write | Open and reply to support tickets. Requires tickets:read. |
| bgp:read | Read ASNs, BGP sessions and prefixes. Account-wide. |
Service and IP restrictions
A key can be limited to selected services: lists then contain only those services, and account-wide scopes (invoices, tickets, BGP) cannot be granted. A key can also be limited to IP addresses or CIDR blocks; requests from other addresses get 403 ip_not_allowed. Keys can expire after 30, 90 or 365 days, or never.
Rate limits
Per key: 120 read and 20 write requests per minute. All keys of an account together: 300 read and 40 write requests per minute. Responses carry X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset; when a limit is exceeded you get 429 with Retry-After.
Server status, overview and power actions also share a capacity with other customers and may return 429 server_rate_limited. Status is cached for 10 seconds and the server overview for 60 seconds, so polling faster does not give fresher data.
Requests and responses
- Responses are JSON: successful responses have success, data and meta.request_id; errors have success false, error.code, error.message and sometimes error.details. Quote the request_id when contacting support.
- Lists accept limit (1-100, default 25) and offset, and return meta.pagination with limit, offset, total and has_more. Unknown or repeated query parameters are rejected with 422.
- Amounts and other decimals are strings, for example 24.00, never floating-point numbers. Amounts come with a separate currency field.
- Timestamps are ISO 8601 with an offset (Z for UTC; appointment times use +03:00). Calendar days are YYYY-MM-DD. Energy days and months are UTC.
- Field names are snake_case. Status values may gain new values within v1; treat unknown values gracefully.
{
"success": true,
"data": [ { "id": 123, "product_name": "VDS 4", "status": "active", "recurring_amount": "24.00", "currency": "USD" } ],
"meta": {
"request_id": "7f3c9a2e-…",
"pagination": { "limit": 10, "offset": 0, "total": 1, "has_more": false }
}
}Retries and idempotency
Write endpoints accept an Idempotency-Key header (1-64 characters: letters, digits, '.', '_', ':' or '-'). Retrying with the same key within 24 hours returns the original response with Idempotent-Replayed: true instead of repeating the action. Reusing a key with a different body returns 422 idempotency_key_reused. After a timeout (504) the action may still complete: retry with the same key rather than a new one.
Endpoints
| Endpoint | Scope | Description |
|---|---|---|
| GET /me | any | The calling key: scopes, restrictions, expiry and account. |
| GET /departments | any | Department keys for opening tickets. |
| GET /services | services:read | Your services, active first. |
| GET /services/{id} | services:read | One service, including whether it has a managed server. |
| GET /services/{id}/server | services:read | Server overview: hardware, addresses, OS and available operations. |
| GET /services/{id}/server/status | services:read | Live power state and resource usage. |
| POST /services/{id}/server/power | servers:power | Start, stop, restart or power off a server. |
| GET /invoices | invoices:read | Your invoices, newest first. |
| GET /invoices/{id} | invoices:read | One invoice with its lines and official document status. |
| GET /tickets | tickets:read | Your support tickets. |
| GET /tickets/{id} | tickets:read | One ticket with its messages. |
| POST /tickets | tickets:write | Open a support ticket. |
| POST /tickets/{id}/replies | tickets:write | Reply to a ticket (reopens a closed ticket). |
| GET /bgp/asns | bgp:read | Your ASNs and their verification. |
| GET /bgp/sessions | bgp:read | Your BGP sessions. |
| GET /bgp/prefixes | bgp:read | Your prefixes with approval, RPKI/IRR and upstream state. |
| GET /domains | domains:read | Your domains (read-only; transfer codes are never returned). |
| GET /metrics/energy | energy:read | Monthly energy consumption per meter. |
| GET /metrics/energy/series | energy:read | Energy consumption as an hourly, daily or monthly series. |
| GET /metrics/energy/live | energy:read | Live power draw per cabinet and feed imbalance alerts. |
Examples
List the first ten services:
curl https://api.zenix.net.tr/v1/services?limit=10 \ -H "Authorization: Bearer $ZENIX_API_KEY"
Restart a server, safe to retry:
curl -X POST https://api.zenix.net.tr/v1/services/123/server/power \
-H "Authorization: Bearer $ZENIX_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: restart-123-20261020" \
-d '{"action":"restart"}'Errors
Every error has a stable machine-readable code. Messages are fixed English text and may change; build your logic on the code.
{
"success": false,
"error": { "code": "insufficient_scope", "message": "…", "details": { "required_scope": "servers:power" } },
"meta": { "request_id": "7f3c9a2e-…" }
}| HTTP | Code | Message |
|---|---|---|
| 400 | invalid_path | The request path is not valid. |
| 400 | invalid_json | The request body is not valid UTF-8 JSON. |
| 400 | invalid_idempotency_key | Idempotency-Key must be 1-64 characters: letters, digits, '.', '_', ':' or '-', starting with a letter or digit. |
| 400 | invalid_request | The request could not be processed. |
| 401 | missing_api_key | Missing API key. Send it as 'Authorization: Bearer <key>'. |
| 401 | invalid_api_key | The API key is invalid, expired or revoked. |
| 403 | insufficient_scope | The API key does not have the scope required for this endpoint. |
| 403 | service_scope_restricted | This API key is limited to specific services and cannot access account-wide data. |
| 403 | ip_not_allowed | Requests from this IP address are not allowed for this API key. |
| 404 | not_found | The requested resource was not found. |
| 404 | service_not_found | Service not found. |
| 404 | server_not_found | This service has no managed server. |
| 404 | invoice_not_found | Invoice not found. |
| 404 | ticket_not_found | Ticket not found. |
| 404 | cabinet_not_found | Cabinet not found. |
| 405 | method_not_allowed | The HTTP method is not allowed for this endpoint. |
| 409 | server_busy | Another operation is in progress on this server. |
| 409 | server_not_ready | The server is not ready yet. |
| 409 | service_not_active | The service is not active. |
| 409 | server_management_unavailable | Power and status operations are not available for this server. |
| 409 | idempotency_key_in_use | A request with this Idempotency-Key is still being processed. Retry shortly with the same key. |
| 413 | payload_too_large | The request body is too large. |
| 415 | unsupported_media_type | The request body must be application/json. |
| 422 | validation_failed | The request contains invalid parameters. |
| 422 | idempotency_key_reused | This Idempotency-Key was already used with a different request. |
| 429 | rate_limit_exceeded | Too many requests. Retry after the time in the Retry-After header. |
| 429 | server_rate_limited | Too many server operations right now. Retry after the time in the Retry-After header. |
| 500 | internal_error | An internal error occurred. |
| 502 | server_operation_failed | The server operation could not be completed. |
| 502 | upstream_error | The service returned an invalid response. |
| 503 | api_disabled | The API is temporarily disabled. |
| 503 | service_unavailable | The service is temporarily unavailable. |
| 503 | server_operations_unavailable | Server operations are temporarily unavailable. |
| 504 | upstream_timeout | The request timed out. The operation may still complete; retry with the same Idempotency-Key. |
Versioning
Within v1, fields and enum values may be added, so ignore fields you do not know. Breaking changes are published under a new version path.

