# StarBonding Partner API

Version: `v1`  
Base URL: `https://starbonding.com/api/v1/`

All requests must use HTTPS. The API key must remain on the partner server and must never be placed in browser code, logs, or public repositories.

## Authentication

Send this header on every request:

```http
X-API-Key: YOUR_API_KEY
```

`create.account.php` and `renew.account.php` are financial operations. They additionally require a unique partner-generated key:

```http
Idempotency-Key: PARTNER_GENERATED_UNIQUE_VALUE
```

The key must be 8–128 characters and contain only letters, numbers, `.`, `_`, `:`, or `-`. It is scoped to the authenticated partner and endpoint.

## Response format

Success:

```json
{"success":true,"data":{}}
```

Error:

```json
{"success":false,"error_code":"INSUFFICIENT_BALANCE","error":"Insufficient wallet balance."}
```

Clients must check both the HTTP status and `success`. All monetary fields are integer paise and use names ending in `_paise`. Divide by `100` only when displaying rupees.

## Idempotency and retries

The normalized validated request parameters—not raw JSON property order—are hashed and stored with the partner, endpoint, HTTP status, and complete JSON response.

- Repeating the same endpoint with the same key and identical parameters returns the original HTTP status and JSON response. It does not create another account, renew again, or debit again.
- Reusing a key with different parameters returns HTTP `409`:

```json
{
  "success": false,
  "error_code": "IDEMPOTENCY_CONFLICT",
  "error": "The idempotency key was previously used with a different request."
}
```

- A client may safely retry a timed-out create or renewal using the identical request and the same key.
- Never retry a timed-out financial operation with a new key unless another financial operation is intentionally wanted. A new key represents a new operation.

The idempotency record, managed-account change, and wallet transaction are committed atomically. A database failure before commit rolls them all back.

## Endpoints

### List services

```http
GET /get.service.list.php
```

```bash
curl https://starbonding.com/api/v1/get.service.list.php \
  -H "X-API-Key: YOUR_API_KEY"
```

`data.services[]` contains `serviceid`, `name`, `label`, `days`, `amount_paise`, `amount_rupees`, `kb_allocation`, `restream`, and `is_free`. `amount_paise` is canonical; `amount_rupees` is a deprecated compatibility display field. Always use the returned `serviceid`; do not assume plan IDs.

### Create account

```http
POST /create.account.php
Content-Type: application/json
X-API-Key: YOUR_API_KEY
Idempotency-Key: create-customer-20260819-0001
```

Request:

```json
{"serviceid":2,"name":"Customer name","email":"customer@example.com"}
```

`serviceid` and `name` are required. `email` is optional and defaults to the partner email.

```bash
curl -X POST https://starbonding.com/api/v1/create.account.php \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Idempotency-Key: create-customer-20260819-0001" \
  -H "Content-Type: application/json" \
  -d '{"serviceid":2,"name":"Customer name","email":"customer@example.com"}'
```

`data.account` contains `userid`, `name`, `username`, `password`, `email`, `serviceid`, `service_name`, `validfrom`, `validtill`, `restream_count`, and `status`.

For paid accounts, `data.transaction` contains `transactionid`, `amount_paise`, `charge_paise`, `credit_paise`, `opening_balance_paise`, `closing_balance_paise`, `reference`, and `status`. `data.balance_paise` is the resulting wallet balance. For a free service, `transaction` is `null` and no debit is made.

The legacy aliases `opening` and `closing` may also be present for compatibility; they are deprecated and are numerically paise. Use the explicitly named `_paise` fields.

### Renew account

```http
POST /renew.account.php
Content-Type: application/json
X-API-Key: YOUR_API_KEY
Idempotency-Key: renew-account-20260819-0001
```

Request:

```json
{"username":"ACCOUNT_USERNAME","serviceid":2}
```

`serviceid` is required. Supply either `username` or `userid`; if both are supplied, `userid` is used. The account must have logged in at least once.

```bash
curl -X POST https://starbonding.com/api/v1/renew.account.php \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Idempotency-Key: renew-account-20260819-0001" \
  -H "Content-Type: application/json" \
  -d '{"username":"ACCOUNT_USERNAME","serviceid":2}'
```

`data.account` contains the updated account. `data.renewal` contains `current_serviceid`, `current_days`, `current_restream`, `same_restream`, `remaining_seconds`, `valid_from`, and `valid_till`. `data.transaction` contains canonical `amount_paise`, `charge_paise`, `credit_paise`, `prorata_credit_paise`, `threshold_credit_paise`, `opening_balance_paise`, `closing_balance_paise`, `transactionid`, `reference`, and `status`.

When the restream count is unchanged, unused validity remains before the extension. When it changes, the new plan begins immediately and unused validity is credited where applicable.

### List managed accounts

```http
GET /get.account.list.php?page=1
```

Returns up to 100 accounts per page, newest first. `data` contains `page`, `per_page`, `total_accounts`, `total_pages`, and `accounts[]`. Account-list objects contain `userid`, `name`, `username`, `email`, `serviceid`, `service_name`, `validfrom`, `validtill`, `restream_count`, and `status`.

### Get wallet balance

```http
GET /get.balance.php
```

`data` contains `accountid`, `email`, `balance_paise`, `creditlimit_paise`, and `available_paise`. `available_paise` is the balance plus the configured credit limit.

### Get wallet transactions

```http
GET /get.transactions.php?userid=214&fromdate=2026-08-01&todate=2026-08-31
```

All query parameters are optional. `userid` filters to one managed account. `fromdate` is inclusive and `todate` is inclusive; internally the end filter is the first instant after `todate`.

Each transaction contains `transid`, `recordtime`, `serviceid`, `notes`, `amount_paise`, `type`, `opening_balance_paise`, `closing_balance_paise`, `reference`, `status`, `transaction_kind`, `partner_userid`, `retail_price_paise`, `partner_percentage`, and `activation_month`.

## Timezone and expiry semantics

The deployed application configuration uses `APP_TZ=Asia/Kolkata` by default (PHP timezone identifier; equivalent UTC offset is `+05:30` for the current configuration). API-generated `validfrom`, `validtill`, and wallet `recordtime` values are local timestamps in that configured timezone and are formatted as `YYYY-MM-DD HH:MM:SS` without an offset. Date filters are interpreted in the same configured timezone.

Validity is calculated in whole seconds from the stored timestamps. An account is considered valid while the current time is strictly before `validtill`; at `validtill` it is expired. A renewal with the same restream count starts at the later of now and the current expiry.

## Stable error codes

| Code | Typical HTTP status | Meaning |
|---|---:|---|
| `INVALID_API_KEY` | 401 | Missing or invalid API key. |
| `MISSING_PARAMETER` | 400 | Required parameter is missing. |
| `INVALID_PARAMETER` | 400 | Parameter format or value is invalid. |
| `INVALID_JSON` | 400 | Request JSON is malformed. |
| `INVALID_SERVICE` | 400/422 | Service is missing, invalid, or unavailable. |
| `ACCOUNT_NOT_FOUND` | 422 | Managed account does not belong to this partner or was not found. |
| `ACCOUNT_NOT_ACTIVATED` | 422 | Account must log in before renewal. |
| `INSUFFICIENT_BALANCE` | 402 | Wallet balance and credit limit are insufficient. |
| `IDEMPOTENCY_KEY_REQUIRED` | 400 | Financial request omitted `Idempotency-Key`. |
| `INVALID_IDEMPOTENCY_KEY` | 400 | Key length or characters are invalid. |
| `IDEMPOTENCY_CONFLICT` | 409 | Same key was used with different parameters. |
| `OPERATION_NOT_ALLOWED` | 422 | Request is valid but the operation is not allowed. |
| `INTERNAL_ERROR` | 500 | Temporary server-side failure. Internal details are not exposed. |

## HTTP status codes

`200` success, `400` invalid request, `401` authentication failure, `402` insufficient balance, `409` idempotency conflict, `422` valid request but operation cannot be completed, and `500` temporary server failure.

## Integration sequence

1. Call the service list and display available plans.
2. Check the wallet balance for paid operations.
3. Generate and persist one unique idempotency key for each intended create or renewal.
4. Submit the financial request and persist the returned account and transaction data securely.
5. On timeout, retry the identical request with the same key.
6. Use account listing and transaction listing for reconciliation, not for deciding whether a timed-out financial request should be repeated.
