# Logspanel API v1

## Base URL

```text
https://logspanel.com/api/v1
```

## Authentication

Create your API key from your Logspanel account dashboard:

```text
User Dashboard -> Change Password -> API Access -> Generate New API Key
```

Copy the key immediately. It is displayed only once. Generating a new API key revokes the previous key.

Send the key as a bearer token on every protected API request:

```http
Accept: application/json
Authorization: Bearer YOUR_API_KEY_HERE
```

Keep API keys on your server only. Do not expose them in browser JavaScript, mobile apps, screenshots, public repositories, or support tickets.

## Supported Abilities

New user-generated API keys are issued with this project's supported abilities:

```text
wallet:read
logs:read
logs:buy
numbers:read
numbers:buy
boosting:read
boosting:buy
orders:read
```

The Logs, Numbers, and Boosting APIs currently use:

```text
wallet:read
logs:read
logs:buy
numbers:read
numbers:buy
boosting:read
boosting:buy
orders:read
```

## Wallet Balance

Required ability: `wallet:read`

```http
GET /wallet
```

Response:

```json
{
  "success": true,
  "data": {
    "balance": "12500.00",
    "currency": "NGN"
  }
}
```

## List Parent Categories

Required ability: `logs:read`

```http
GET /logs/parent-categories
```

Use this endpoint to fetch active parent categories for filters and navigation.

Response data item:

```json
{
  "id": 2,
  "name": "Accounts",
  "description": "Social and premium account logs",
  "image": "uploads/parent_categories/accounts.png",
  "available_categories_count": 8
}
```

## List Log Categories

Required ability: `logs:read`

```http
GET /logs/categories?per_page=25&parent_category_id=2
```

`per_page` accepts values from `1` to `100`.
`parent_category_id` is optional and filters log categories by parent category.

Response data item:

```json
{
  "id": 12,
  "name": "Facebook Logs",
  "description": "Fresh account logs",
  "image": "https://logspanel.com/image.png",
  "price": "2500.00",
  "currency": "NGN",
  "available_quantity": 34,
  "parent_category": {
    "id": 2,
    "name": "Accounts"
  }
}
```

## Get Log Category

Required ability: `logs:read`

```http
GET /logs/categories/12
```

This endpoint returns category, price, and availability information only. Purchased log details are returned only after a successful purchase.

## Purchase Logs

Required ability: `logs:buy`

```http
POST /logs/orders
```

Request:

```json
{
  "category_id": 12,
  "quantity": 2,
  "idempotency_key": "website-order-20260501-0001"
}
```

The server calculates the unit price, total, and wallet deduction. Do not send a price from your integration.

Use a unique `idempotency_key` for each checkout attempt. If your server retries the same request with the same key, the API returns the original response instead of charging twice.

Successful response:

```json
{
  "success": true,
  "data": {
    "order_id": "logs-ABC1234567-1777560000",
    "status": "completed",
    "product_id": 12,
    "product_name": "Facebook Logs",
    "quantity": 2,
    "unit_price": "2500.00",
    "total": "5000.00",
    "currency": "NGN",
    "balance_after": "7500.00",
    "items": [
      {
        "serial": 1,
        "details": "log details here",
        "video": null
      }
    ]
  }
}
```

Idempotent retry responses include:

```http
Idempotent-Replayed: true
```

## List Log Orders

Required ability: `orders:read`

```http
GET /logs/orders?per_page=25
```

Response data item:

```json
{
  "order_id": "logs-ABC1234567-1777560000",
  "status": "completed",
  "product_id": 12,
  "product_name": "Facebook Logs",
  "quantity": 2,
  "unit_price": "2500.00",
  "total": "5000.00",
  "currency": "NGN",
  "created_at": "2026-05-01T12:00:00.000000Z"
}
```

## List Number Countries

Required ability: `numbers:read`

```http
GET /numbers/countries
```

Use this endpoint to fetch countries available for phone number activations.

Response data item:

```json
{
  "id": 1,
  "name": "United States",
  "short": "us",
  "calling_code": "1",
  "region": "North America",
  "image": "https://flagcdn.com/20x15/us.png"
}
```

## List Number Services

Required ability: `numbers:read`

```http
GET /numbers/services?country_id=1
```

The server calculates final wallet prices. Do not calculate customer-facing prices from raw catalog data.

Response data item:

```json
{
  "service_id": "123",
  "service_name": "Telegram",
  "country_id": "1",
  "country_name": "United States",
  "price": "850.00",
  "currency": "NGN",
  "available_quantity": 92,
  "category": "Activation"
}
```

## List Number Area Codes

Required ability: `numbers:read`

```http
GET /numbers/area-codes?country_id=1&service_id=123
```

Area codes are optional and only apply to services/countries that support area filtering. If no specific area codes are available, the API returns `Random` so the integration can purchase any available number.

Response:

```json
{
  "success": true,
  "data": {
    "codes": ["Random"]
  }
}
```

## Purchase Number

Required ability: `numbers:buy`

```http
POST /numbers/orders
```

Request:

```json
{
  "country_id": 1,
  "service_id": 123,
  "selected_area_codes": ["917"],
  "idempotency_key": "number-order-20260501-0001"
}
```

Logspanel calculates the price, reserves the number, deducts the wallet balance, and returns a stable project-owned response.

Successful response:

```json
{
  "success": true,
  "data": {
    "order_id": "123456789",
    "status": "waiting_for_code",
    "number": "+1234567890",
    "service_id": "123",
    "service_name": "Telegram",
    "country_id": "1",
    "country_name": "United States",
    "price": "850.00",
    "currency": "NGN",
    "time_left": 1200,
    "balance_after": "9150.00"
  }
}
```

Idempotent retry responses include:

```http
Idempotent-Replayed: true
```

## List Number Orders

Required ability: `orders:read`

```http
GET /numbers/orders?per_page=25
```

Response data item:

```json
{
  "order_id": "123456789",
  "status": "waiting_for_code",
  "number": "+1234567890",
  "service_id": "123",
  "service_name": "Telegram",
  "country_id": "1",
  "country_name": "United States",
  "price": "850.00",
  "currency": "NGN",
  "code": null,
  "message": "Still waiting...",
  "time_left": 1200,
  "refunded": false,
  "created_at": "2026-05-01T12:00:00.000000Z"
}
```

## Get Number Order

Required ability: `orders:read`

```http
GET /numbers/orders/123456789
```

Retrieves the stored details of a single number order owned by the authenticated account. Use this endpoint for order lookups, audit views, and displaying the most recently saved status without running a live code check.

Response:

```json
{
  "success": true,
  "data": {
    "order_id": "123456789",
    "status": "waiting_for_code",
    "number": "+1234567890",
    "service_id": "123",
    "service_name": "Telegram",
    "country_id": "1",
    "country_name": "United States",
    "price": "850.00",
    "currency": "NGN",
    "code": null,
    "message": "Still waiting...",
    "time_left": 1200,
    "refunded": false,
    "created_at": "2026-05-01T12:00:00.000000Z"
  }
}
```

## Check Number Code

Required ability: `orders:read`

```http
POST /numbers/orders/123456789/check
```

Runs a live code check for the number order and returns the latest status. In production, poll this endpoint every 5-10 seconds after purchase until `code` contains the received SMS verification code.

Response:

```json
{
  "success": true,
  "data": {
    "order_id": "123456789",
    "status": "completed",
    "number": "+1234567890",
    "service_id": "123",
    "service_name": "Telegram",
    "country_id": "1",
    "country_name": "United States",
    "price": "850.00",
    "currency": "NGN",
    "code": "12345",
    "message": "Code Received",
    "time_left": 875,
    "refunded": false,
    "created_at": "2026-05-01T12:00:00.000000Z"
  }
}
```

## Cancel Number

Required ability: `numbers:buy`

```http
POST /numbers/orders/123456789/cancel
```

Cancels and refunds an eligible number order when no SMS code has arrived.

## List Boost Categories

Required ability: `boosting:read`

```http
GET /boost/categories
```

Returns unique boost categories for service filtering.

Response:

```json
{
  "success": true,
  "data": [
    { "name": "Instagram Followers" },
    { "name": "TikTok Views" }
  ]
}
```

## List Boost Services

Required ability: `boosting:read`

```http
GET /boost/services?category=Instagram%20Followers
```

The API fetches available boost services and returns final NGN wallet prices. `category` is optional.

Response data item:

```json
{
  "service_id": "101",
  "service_name": "Instagram Followers",
  "category": "Instagram Followers",
  "type": "Default",
  "rate_per_1000": "1500.00",
  "usd_rate_per_1000": "1.0000",
  "currency": "NGN",
  "min": 100,
  "max": 10000,
  "refill": false,
  "cancel": false
}
```

## Get Boost Service

Required ability: `boosting:read`

```http
GET /boost/services/101
```

Use this endpoint before checkout to determine the service type, min/max quantity, cancellation support, and required request fields.

## Purchase Boost

Required ability: `boosting:buy`

```http
POST /boost/orders
```

Request for a `Default` service:

```json
{
  "service_id": "101",
  "link": "https://instagram.com/p/example",
  "quantity": 1000,
  "idempotency_key": "boost-order-20260502-0001"
}
```

Logspanel calculates the price, creates the boost order, deducts the wallet balance, and stores the order locally. Do not send price from your integration.

Successful response:

```json
{
  "success": true,
  "data": {
    "order_id": "987654321",
    "status": "pending",
    "service_id": "101",
    "service_name": "Instagram Followers",
    "category": "Instagram Followers",
    "type": "Default",
    "link": "https://instagram.com/p/example",
    "quantity": 1000,
    "price": "1500.00",
    "currency": "NGN",
    "cancel": true,
    "balance_after": "8500.00"
  }
}
```

Idempotent retry responses include:

```http
Idempotent-Replayed: true
```

## List Boost Orders

Required ability: `orders:read`

```http
GET /boost/orders?per_page=25
```

Response data item:

```json
{
  "order_id": "987654321",
  "status": "processing",
  "service_id": "101",
  "service_name": "Instagram Followers",
  "link": "https://instagram.com/p/example",
  "quantity": 1000,
  "price": "1500.00",
  "currency": "NGN",
  "start_count": 120,
  "remains": 350,
  "refunded": false,
  "cancel": true,
  "created_at": "2026-05-02T12:00:00.000000Z"
}
```

## Get Boost Order

Required ability: `orders:read`

```http
GET /boost/orders/987654321
```

Retrieves the latest locally stored boost order owned by the authenticated account.

## Check Boost Status

Required ability: `orders:read`

```http
POST /boost/orders/987654321/check
```

Runs a live status refresh for the boost order and returns the updated local record. If the order is cancelled, the refund-safe processor marks it refunded and credits the user's wallet once.

## Cancel Boost Order

Required ability: `boosting:buy`

```http
POST /boost/orders/987654321/cancel
```

Submits a cancellation request for an eligible boost order. Refunds are completed only after the order status confirms as cancelled.

Successful response:

```json
{
  "success": true,
  "message": "Cancellation request submitted.",
  "data": {
    "order_id": "987654321",
    "status": "canceling",
    "service_id": "101",
    "service_name": "Instagram Followers",
    "link": "https://instagram.com/p/example",
    "quantity": 1000,
    "price": "1500.00",
    "currency": "NGN",
    "start_count": null,
    "remains": null,
    "refunded": false,
    "cancel": false,
    "created_at": "2026-05-02T12:00:00.000000Z"
  }
}
```

## Error Format

```json
{
  "success": false,
  "status": 402,
  "message": "Insufficient wallet balance.",
  "code": "INSUFFICIENT_BALANCE"
}
```

Common error codes:

```text
USER_DISABLED
USER_BANNED
UNAUTHENTICATED
VALIDATION_FAILED
METHOD_NOT_ALLOWED
LOG_CATEGORY_NOT_FOUND
INSUFFICIENT_BALANCE
OUT_OF_STOCK
NUMBER_SERVICE_NOT_FOUND
NUMBER_ORDER_NOT_FOUND
NUMBER_OUT_OF_STOCK
NUMBER_PRICE_CHANGED
NUMBER_CODE_ALREADY_RECEIVED
NUMBER_REFUND_FAILED
BOOST_SERVICE_NOT_FOUND
BOOST_ORDER_NOT_FOUND
BOOST_CANCEL_UNAVAILABLE
BOOST_CANCEL_REJECTED
BOOST_QUANTITY_REQUIRED
BOOST_QUANTITY_OUT_OF_RANGE
BOOST_LINK_REQUIRED
TOOL_NOT_FOUND
TOOL_ORDER_NOT_FOUND
TOOL_ALREADY_OWNED
TOOL_DOWNLOAD_NOT_AVAILABLE
TOOL_DOWNLOAD_FAILED
IDEMPOTENCY_KEY_REUSED
```

Missing, invalid, or revoked API keys return:

```json
{
  "success": false,
  "status": 401,
  "message": "Unauthenticated. Please provide a valid bearer token.",
  "code": "UNAUTHENTICATED"
}
```

Generate a new API key from your account dashboard if a key is lost or compromised.

## cURL Example

```bash
curl -X POST "https://your-domain.com/api/v1/logs/orders" \
  -H "Accept: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{"category_id":12,"quantity":1,"idempotency_key":"website-order-20260501-0001"}'
```
