# KarteSim Documentation

KarteSim gives partners real phone numbers and mobile IPs through two services: long-term **number & proxy rentals** and per-use **OTP sessions**. Both are available via the modern Native REST API and the legacy Handler API.

---

## Authentication

All API requests require your partner API key. How you pass it depends on your protocol.

**Handler API — query parameter:**
```bash
GET /api/stubs/handler_api.php
  ?api_key=YOUR_KEY
  &action=getBalance
```

**Native REST API — HTTP header:**
```bash
curl https://api.kartesim.com/api/v1/otp/request \
  -H "x-api-key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"service": "telegram"}'
```

**Security Warning:** Keep your API key secret. Your key is visible in the partner portal under API. Use the Regenerate Key button there to rotate it instantly.

---

## Handler API Reference

Base URL: `/api/stubs/handler_api.php` — All requests use `GET`. All responses are plain text.

### `action=getBalance`
Returns your current pre-paid balance in USD.
- **Example Request:** `curl 'https://api.kartesim.com/api/stubs/handler_api.php?api_key=YOUR_KEY&action=getBalance'`
- **Example Response:** `45.00`
- **Error Response:** `BAD_KEY` (Invalid or revoked API key)

### `action=getCountries`
List supported countries with their numeric codes.
- **Example Request:** `curl 'https://api.kartesim.com/api/stubs/handler_api.php?api_key=YOUR_KEY&action=getCountries'`
- **Example Response:**
  ```json
  [
    { "id": 7,   "name": "Russia" },
    { "id": 212, "name": "Morocco" }
  ]
  ```

### `action=getPrices`
Get current pricing and available active stock per country and service.
- **Parameters:** 
  - `country` (optional): Filter by numeric country ID.
  - `hide_empty` (optional): Set to 1 to exclude countries with zero stock.
- **Example Request:** `curl 'https://api.kartesim.com/api/stubs/handler_api.php?api_key=YOUR_KEY&action=getPrices&hide_empty=1'`
- **Example Response:**
  ```json
  {
    "212": {
      "wa": { "cost": 0.15, "count": 12 },
      "tg": { "cost": 0.15, "count": 12 }
    }
  }
  ```

### `action=getNumber`
Request a temporary phone number for OTP verification. Returns a session ID and the assigned number. The session expires after 10 minutes if no SMS arrives.
- **Parameters:**
  - `service` (optional): Service name (e.g. "telegram").
  - `country` (optional): Country calling code.
- **Example Request:** `curl 'https://api.kartesim.com/api/stubs/handler_api.php?api_key=YOUR_KEY&action=getNumber&service=telegram&country=212'`
- **Example Response:** `ACCESS_NUMBER:cma4x9k3b0000abc123:212661234567`
- **Error Responses:** `NO_NUMBERS`, `NO_BALANCE`

### `action=getStatus`
Poll for the OTP code on an active session. Poll every 5–10 seconds until you receive STATUS_OK or STATUS_CANCEL.
- **Parameters:** `id` (required): Session ID from ACCESS_NUMBER response.
- **Example Request:** `curl 'https://api.kartesim.com/api/stubs/handler_api.php?api_key=YOUR_KEY&action=getStatus&id=cma4x9k3b0000abc123'`
- **Example Response:** `STATUS_OK:84729`
- **Other Responses:** `STATUS_WAIT_CODE`, `STATUS_CANCEL`

### `action=setStatus`
Confirm receipt of the OTP (status=1) or cancel the session for a full refund (status=8). Only PENDING sessions can be cancelled.
- **Parameters:**
  - `id` (required): Session ID
  - `status` (required): 1 = confirm, 8 = cancel
- **Example Request:** `curl 'https://api.kartesim.com/api/stubs/handler_api.php?api_key=YOUR_KEY&action=setStatus&id=cma4x9k3b0000abc123&status=8'`
- **Example Response:** `ACCESS_CANCEL`
- **Other Responses:** `ACCESS_READY`, `BAD_ACTION`

---

## Native REST API

For modern integrations, use our Native REST API. Pass your API key using the `x-api-key` HTTP header.

### OTP Sessions (per use)

**1. Request OTP Session** (`POST /api/v1/otp/request`)
- **Body:** `{ "service": "telegram", "country": 212, "webhookUrl": "https://...", "expiresIn": 600 }`
- **Responses:**
  - `200 OK`: `{ "sessionId": "cma...", "number": "212661234567", "status": "PENDING", "expiresAt": "..." }`
  - `402 Payment Required`: Insufficient balance.
  - `503 Service Unavailable`: No online numbers available.

**2. Get OTP Session Status** (`GET /api/v1/otp/:sessionId`)
- **Responses:**
  - `200 OK — PENDING`: `status: "PENDING", otp: null`
  - `200 OK — RECEIVED`: `status: "RECEIVED", otp: "84729"`
  - `200 OK — EXPIRED`: `status: "EXPIRED"`
  - `200 OK — CANCELLED`: `status: "CANCELLED"`

**3. Cancel OTP Session** (`POST /api/v1/otp/:sessionId/cancel`)
- **Responses:**
  - `200 OK`: `{ "sessionId": "cma...", "status": "CANCELLED", "refunded": "0.1000" }`
  - `409 Conflict`: Session is not PENDING.

**Webhook Payload (otp.received):**
If you provided a `webhookUrl`, we POST this payload when the OTP arrives:
```json
{
  "event":      "otp.received",
  "sessionId":  "cma4x9k3b0000abc123",
  "status":     "RECEIVED",
  "number":     "212661234567",
  "otp":        "84729",
  "smsBody":    "Your Telegram code is 84729",
  "receivedAt": "2026-06-21T12:00:00.000Z"
}
```
*Note: Your webhook URL must be HTTPS. We send an `X-Webhook-Signature: sha256=...` header (HMAC-SHA256) for verification.*

### Number Rentals (SIM cards)

Number rentals give you exclusive use of a real SIM card for a fixed rental period (Daily, Weekly, Monthly). Every SMS received on that number is delivered to your account in real time.

**1. Browse Available Numbers** (`GET /api/v1/numbers/available?country=212`)
- **Response:**
  ```json
  {
    "available": [{
      "phoneId":      "clx...",
      "maskedNumber": "+212 6** *** **7",
      "countryCode":  212,
      "country":      "Morocco",
      "carrier":      "Orange",
      "pricing": { "daily": null, "weekly": 2.50, "monthly": 8.00 }
    }],
    "total": 1
  }
  ```

**2. Rent a Number** (`POST /api/v1/numbers/rent`)
- **Body:** `{ "phoneId": "clx...", "billingCycle": "MONTHLY", "cycles": 1 }`
- **Response:** Returns the full, unmasked phone number and deductions details.

**3. List Your Rentals** (`GET /api/partner/rentals`)
- **Response:** JSON array of active number rentals.

**4. Get SMS for Rental** (`GET /api/partner/sms?simNumber=1234567890`)
- **Response:** JSON array of recent SMS messages received on your rented number.

### Proxy Rentals (Mobile IPs)

Each phone exposes an HTTP and SOCKS5 proxy over its mobile data connection.
- **HTTP:** device-specific port
- **SOCKS5:** default port 1080

**Examples:**
```bash
# HTTP
curl --proxy http://USER:PASS@PHONE_IP:8888 https://api.ipify.org
# SOCKS5
curl --proxy socks5://USER:PASS@PHONE_IP:1080 https://api.ipify.org
```

**1. List Your Proxies** (`GET /api/partner/proxies`)
- **Response:** JSON array containing proxy details, IP address, ports, and credentials.

---

## Supported Countries

Use `getCountries` to get the current list. Common country codes:
- `0`: Any (auto-assign)
- `1`: United States
- `44`: United Kingdom
- `49`: Germany
- `33`: France
- `34`: Spain
- `212`: Morocco
- `971`: UAE

---

## Error Reference

| Response | Meaning |
|---|---|
| `BAD_KEY` | Invalid, revoked, or missing API key |
| `BAD_ACTION` | Unknown action or missing required parameters |
| `TOO_MANY_REQUESTS` | Rate limit exceeded — 120 requests per minute |
| `NO_NUMBERS` | No online phones available matching your OTP request |
| `NO_BALANCE` | Insufficient balance to create an OTP session |
| `STATUS_WAIT_CODE` | OTP not yet received — keep polling |
| `STATUS_OK:code` | OTP received — digit code follows the colon |
| `STATUS_CANCEL` | Session expired or was cancelled |
| `ACCESS_NUMBER:id:num` | OTP session created — session ID and phone number follow |
| `ACCESS_CANCEL` | Session cancelled, balance refunded |
| `ACCESS_READY` | Session acknowledged / confirmed |
