Skip to content

API Authentication

The enconf REST API provides programmatic access to all hosting features. This page describes the available authentication methods, the token format and rate limiting.


Base URL

All API endpoints are available at the following base URL:

https://your-panel.com:3443/api/v1

Port 3443

The panel runs on port 3443 by default. The API is accessible on the same port.

Interactive API Documentation

A complete, interactive API reference with all endpoints, parameters and example responses is available directly in your panel:

https://your-panel.com:3443/api/docs

You can test all API calls directly in your browser (Swagger UI). Authenticate via the Authorize button using your API key or JWT token.

For WHMCS / HostBill developers

The OpenAPI specification (YAML) is available at https://your-panel.com:3443/api/docs/openapi.yaml and can be imported directly into your development environment.


Authentication Methods

The API supports two authentication methods:

Method Use Case Validity
JWT Token Interactive use, frontend Configurable (default: 24 hours)
API Key Automation, scripts, integrations Until expiration date or manual deletion

JWT Token (Login)

For interactive use, authenticate with email and password to receive a JWT token.

Login Request

POST /api/v1/auth/login
Content-Type: application/json

{
  "email": "customer@example.com",
  "password": "YourPassword"
}

Successful Response

{
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIs...",
    "user": {
      "id": 42,
      "email": "customer@example.com",
      "name": "John Doe",
      "role": "customer"
    }
  },
  "error": null,
  "message": "Login successful"
}

Login with 2FA

If two-factor authentication is enabled, the login additionally requires a TOTP code:

POST /api/v1/auth/login
Content-Type: application/json

{
  "email": "customer@example.com",
  "password": "YourPassword",
  "totp_code": "123456"
}

If the TOTP code is missing and 2FA is enabled, the API responds with:

{
  "data": null,
  "error": "2fa_required",
  "message": "Two-factor authentication code required"
}

Using the Token

Send the token in the Authorization header with all subsequent requests:

GET /api/v1/sites
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

Token Validity

Setting Default Value
Validity Period 24 hours (configurable by admin)
Algorithm HS256 (HMAC-SHA256)

After the token expires, you must log in again.


API Keys

API keys are ideal for automation, deployment scripts and integrations with third-party systems.

Create API Key

POST /api/v1/auth/api-keys
Authorization: Bearer <jwt-token>
Content-Type: application/json

{
  "name": "Deployment Script",
  "expires_at": "2027-12-31T23:59:59Z"
}
Field Required Description
name Yes Label (1–100 characters)
expires_at No Expiration date in RFC 3339 format

Response

{
  "data": {
    "id": 1,
    "name": "Deployment Script",
    "key": "ncp_a1b2c3d4e5f6...",
    "key_prefix": "ncp_a1b2c3d4e5f6",
    "expires_at": "2027-12-31T23:59:59Z",
    "created_at": "2026-03-31T10:00:00Z"
  },
  "error": null,
  "message": "API key created"
}

Key Visible Only Once

The key field is returned only in this response. Store the key securely immediately. Only a SHA-256 hash of the key is stored in the database — the plaintext cannot be recovered.

Using an API Key

Send the key in the Authorization header:

GET /api/v1/sites
Authorization: Bearer ncp_a1b2c3d4e5f6...

List API Keys

GET /api/v1/auth/api-keys
Authorization: Bearer <jwt-token>

Response:

{
  "data": [
    {
      "id": 1,
      "name": "Deployment Script",
      "key_prefix": "ncp_a1b2c3d4e5f6",
      "last_used_at": "2026-03-30T14:22:00Z",
      "expires_at": "2027-12-31T23:59:59Z",
      "created_at": "2026-03-31T10:00:00Z"
    }
  ],
  "error": null,
  "message": ""
}

key_prefix

The key_prefix shows the first 20 characters of the key and serves for identification. The full key is never displayed again.

Delete API Key

DELETE /api/v1/auth/api-keys/:id
Authorization: Bearer <jwt-token>

Key Format

API keys use the following format:

ncp_<64 hex characters>
  • Prefix: ncp_ (NetCell Panel)
  • 32 bytes of random data, hex-encoded
  • Total length: 68 characters

Response Format

All API responses use a consistent JSON format:

{
  "data": { ... },
  "error": null,
  "message": "Description"
}
Field Type Description
data Object/Array/null The requested data
error String/null Error description (null on success)
message String Human-readable message

Error Responses

HTTP Status Meaning
400 Bad request (missing or invalid parameters)
401 Not authenticated (token missing or invalid)
403 Forbidden (insufficient role or resource belongs to another customer)
404 Resource not found
409 Conflict (e.g. duplicate)
422 Validation error
429 Too many requests (rate limit exceeded)
500 Internal server error

Example error response:

{
  "data": null,
  "error": "not authenticated",
  "message": "Authentication required"
}

Rate Limiting

The API limits the number of requests per time period to prevent abuse:

Endpoint Limit
Login (/auth/login) 10 requests per minute per IP
Password Reset 5 requests per minute per IP
All Other Endpoints 120 requests per minute per user

When the rate limit is exceeded, the API responds with HTTP status 429:

{
  "data": null,
  "error": "rate limit exceeded",
  "message": "Too many requests. Please try again later."
}

Rate Limit Headers

The API sends the following headers with every response:

Header Description
X-RateLimit-Limit Maximum requests per time window
X-RateLimit-Remaining Remaining requests
X-RateLimit-Reset Unix timestamp when the limit resets

Subscription Context

Customer endpoints require the context of a subscription. Pass the subscription ID as a query parameter:

GET /api/v1/sites?subscription_id=5
Authorization: Bearer <token>

If the parameter is missing and the customer has multiple subscriptions, the default subscription is used.


Examples

cURL

# Login
TOKEN=$(curl -s -X POST https://panel.example.com:3443/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"customer@example.com","password":"secret"}' \
  | jq -r '.data.token')

# List websites
curl -s https://panel.example.com:3443/api/v1/sites?subscription_id=1 \
  -H "Authorization: Bearer $TOKEN" | jq

# With API key
curl -s https://panel.example.com:3443/api/v1/sites?subscription_id=1 \
  -H "Authorization: Bearer ncp_a1b2c3d4..." | jq

Python

import requests

BASE_URL = "https://panel.example.com:3443/api/v1"

# Login
resp = requests.post(f"{BASE_URL}/auth/login", json={
    "email": "customer@example.com",
    "password": "secret"
})
token = resp.json()["data"]["token"]

headers = {"Authorization": f"Bearer {token}"}

# List websites
sites = requests.get(f"{BASE_URL}/sites",
    headers=headers,
    params={"subscription_id": 1}
)
print(sites.json())

PHP

<?php
$baseUrl = 'https://panel.example.com:3443/api/v1';
$apiKey  = 'ncp_a1b2c3d4...';

$ch = curl_init("$baseUrl/sites?subscription_id=1");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer $apiKey",
        "Content-Type: application/json",
    ],
]);

$response = curl_exec($ch);
$data = json_decode($response, true);
print_r($data);