# ClaudeOTP API (v1.1.0)

> REST API for virtual phone numbers (SMS OTP), social media services (SMM), Gmail accounts, email rental and ready-made WhatsApp numbers. All products share one balance.

- Base URL: https://claudeotp.com/api/v1
- OpenAPI 3.0 spec: https://claudeotp.com/openapi.json
- HTML docs: https://claudeotp.com/api-docs

## Authentication

Every request needs your API key. Find it in Dashboard → Profile → API. Send it as the `X-API-Key` header (recommended), `Authorization: Bearer <key>`, or the `apikey` query parameter. Keep the key secret; if it leaks, contact support and we will rotate it.

## Conventions

- Base URL: `https://claudeotp.com/api/v1`. Request bodies may be JSON (`Content-Type: application/json`) or form-encoded; file uploads use `multipart/form-data`.
- Every response is JSON with `success` (boolean), `message` and `data`. Always check `success` before reading `data`.
- Errors also carry a machine-readable `error_code` (see Error codes) and a `request_id`. Branch on `error_code`, not on `message` — message text may change.
- Amounts are integers in Indonesian Rupiah (IDR). Timestamps are ISO 8601 or `Y-m-d H:i:s` in Asia/Jakarta (UTC+7).
- Rate limit: 360 requests per minute per API key. Watch the `X-RateLimit-Remaining` header; HTTP 429 means wait and retry.
- Idempotency: purchase endpoints accept an optional `Idempotency-Key` header (8–128 chars). Retrying with the same key within 24 h returns the first result instead of buying twice — use a fresh UUID per purchase.
- Every response has an `X-Request-Id` header. Include it when contacting support.

## Quick start (virtual number)

1. Check your balance: `GET /balance`
2. Find the service id (e.g. WhatsApp): `GET /services`
3. List countries & prices for that service; pick an entry `id`: `GET /services/{service_id}/countries`
4. Buy a number: `POST /orders`
5. Poll every 5–10 s until `latest_code` is filled: `GET /orders/{order_uuid}`
6. Finish the order when done, or cancel it for a refund if no SMS arrives: `POST /orders/{order_uuid}/finish`

## Account

Balance and profile of the API key owner.

### GET /balance

Get balance. Live balance. Cached for up to 5 seconds.

```bash
curl -X GET 'https://claudeotp.com/api/v1/balance' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "balance": 305932,
        "balance_formatted": "Rp 305.932",
        "bonus_balance": 0,
        "pending_balance": 0,
        "currency": "IDR"
    },
    "message": "Balance retrieved successfully"
}
```

### GET /profile

Get profile. Account details and active-order stats. The balance here may lag a few seconds behind /balance.

```bash
curl -X GET 'https://claudeotp.com/api/v1/profile' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "user": {
            "id": 2621,
            "name": "Jane",
            "email": "jane@example.com",
            "balance": "Rp 305.932",
            "created_at": "2026-01-01T00:00:00.000000Z"
        },
        "stats": {
            "total_orders": 1,
            "total_sms": 0,
            "balance_raw": 305932
        }
    },
    "message": "Profile loaded successfully"
}
```

## Virtual numbers (SMS OTP)

Rent a phone number, receive the verification SMS, then finish or cancel. Cancelling before an SMS arrives refunds the full price.

### GET /services

List services. All apps/websites you can receive codes for. Cache this list; it rarely changes.

```bash
curl -X GET 'https://claudeotp.com/api/v1/services' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": [
        {
            "id": 1276,
            "text": "Whatsapp",
            "description": null,
            "icon": "https://…/svc_ic_1276.webp"
        },
        {
            "id": 718,
            "text": "Google / Youtube / Gmail",
            "description": null,
            "icon": "https://…"
        }
    ],
    "message": "Services retrieved successfully"
}
```

### GET /services/{id}

Get one service

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | integer | yes | Service id from /services |

```bash
curl -X GET 'https://claudeotp.com/api/v1/services/1276' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "id": 1276,
        "text": "Whatsapp",
        "description": null,
        "icon": "https://…"
    },
    "message": "Service details retrieved successfully"
}
```

### GET /services/{id}/countries

Countries & prices for a service. Each entry is one purchasable offer (country + server + operator). Use the entry `id` as `country` when creating an order. `stock`, `delivery_percent` and `can_order` help you choose; prices change, so read them right before ordering.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | integer | yes | Service id from /services |

```bash
curl -X GET 'https://claudeotp.com/api/v1/services/1276/countries' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "status": "success",
        "application_id": 1276,
        "countries": [
            {
                "id": 184809,
                "name": "Indonesia",
                "iso": "ID",
                "prefix": "+62",
                "price": 4720,
                "price_formatted": "Rp 4.720",
                "available": true,
                "provider_id": 3,
                "stock": 110,
                "delivery_percent": 35.8,
                "operator": "any",
                "can_order": true
            }
        ]
    },
    "message": "Service countries retrieved successfully"
}
```

### POST /orders

Buy a number. Charges your balance and reserves a number. Read `order.order_uuid` from the response and poll GET /orders/{order_uuid} for the SMS. With `quantity` > 1 the response also has `orders` and `summary`. The first 3 numbers are created before the response; above 3 the API answers `202` with `background: true` and keeps ordering the rest — poll GET /orders/bulk-status for progress. Ordering stops at the first number that cannot be created (out of stock, balance); you are only charged for numbers created.

Accepts `Idempotency-Key` header.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `service_id` | body | integer | yes | Service id from /services |
| `country` | body | integer | yes | Offer `id` from /services/{id}/countries (not an ISO code) |
| `quantity` | body | integer | no | How many numbers to buy, 1–30 (default 1) |

```bash
curl -X POST 'https://claudeotp.com/api/v1/orders' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -H 'Idempotency-Key: 2f6c1b9e-1d0a-4c55-9a4e-6b8f2c7d1e03' \
  -H 'Content-Type: application/json' \
  -d '{"service_id":1276,"country":184809,"quantity":1}'
```

Response (201):

```json
{
    "success": true,
    "data": {
        "results": [
            {
                "success": true,
                "order_uuid": "FBTO1234567890NUM",
                "order": {
                    "…": "raw order object"
                }
            }
        ],
        "summary": {
            "requested": 1,
            "succeeded": 1,
            "failed": 0
        }
    },
    "order": {
        "id": 6751431,
        "order_uuid": "FBTO1234567890NUM",
        "number": "6281234567890",
        "formatted_number": "+62 812-3456-7890",
        "status": "pending",
        "service": {
            "id": 1276,
            "name": "Whatsapp"
        },
        "country": {
            "id": 6,
            "name": "Indonesia",
            "iso_code": "ID",
            "phone_code": "62"
        },
        "price": 4720,
        "currency": "IDR",
        "latest_code": null,
        "sms_count": 0,
        "messages": [],
        "is_expired": false,
        "remaining_time": 1200,
        "created_at": "2026-10-09 08:15:09",
        "expired_at": "2026-10-09 08:35:09"
    },
    "message": "Order created successfully"
}
```

Typical errors: `insufficient_balance`, `out_of_stock`, `rate_limited`, `provider_unavailable`, `validation_error`

### GET /orders/bulk-status

Progress of a multi-number order. Status of your latest order with `quantity` > 3 (kept 30 minutes). `state` is `running` while the rest are being ordered and `done` when finished; `succeeded` counts numbers created so far. `data` is null when there is no recent bulk order. Only one bulk order can run at a time (a second one gets 409).

```bash
curl -X GET 'https://claudeotp.com/api/v1/orders/bulk-status' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "id": "3f9a1c2b7d10",
        "state": "running",
        "requested": 30,
        "succeeded": 12,
        "failed": 0,
        "message": null,
        "started_at": 1791520000,
        "updated_at": 1791520014
    }
}
```

### GET /orders/{id}

Get one order (poll for the SMS). Recommended polling endpoint. `latest_code` holds the newest code; `messages` lists every SMS newest-first. Poll every 5–10 seconds; responses are cached for 3 seconds. `{id}` is the `order_uuid` (works for any order) or the numeric `id` (active orders only).

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | string | yes | order_uuid (recommended) or numeric order id |
| `check_sms` | query | boolean | no | true (default) asks the provider for new SMS now; false returns stored data only |

```bash
curl -X GET 'https://claudeotp.com/api/v1/orders/FBTO1234567890NUM' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "id": 6751431,
        "order_uuid": "FBTO1234567890NUM",
        "number": "6281234567890",
        "formatted_number": "+62 812-3456-7890",
        "status": "completed",
        "service": {
            "id": 1276,
            "name": "Whatsapp"
        },
        "country": {
            "id": 6,
            "name": "Indonesia",
            "iso_code": "ID",
            "phone_code": "62"
        },
        "operator": "any",
        "price": 4720,
        "currency": "IDR",
        "latest_code": "504374",
        "sms_count": 1,
        "messages": [
            {
                "code": "504374",
                "text": "Your WhatsApp code: 504-374",
                "received_at": "2026-10-09T08:16:02+07:00"
            }
        ],
        "can_cancel": false,
        "can_finish": true,
        "is_expired": false,
        "remaining_time": 912,
        "created_at": "2026-10-09 08:15:09",
        "expired_at": "2026-10-09 08:35:09"
    },
    "message": "Order retrieved successfully"
}
```

Typical errors: `order_not_found`

### GET /orders/active

List active orders. All orders still waiting or receiving SMS, plus your order limits. SMS arrays here are oldest-first; prefer GET /orders/{id} when you need the latest code.

```bash
curl -X GET 'https://claudeotp.com/api/v1/orders/active' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "success": true,
        "orders": [
            {
                "id": 6751431,
                "order_uuid": "FBTO1234567890NUM",
                "number": "6281234567890",
                "status": "pending",
                "sms": [],
                "remaining_time": 1150
            }
        ],
        "count": 1,
        "has_active_orders": true,
        "order_limits": {
            "…": "…"
        }
    },
    "message": "Active orders retrieved successfully"
}
```

### GET /orders/history

Order history (completed)

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `page` | query | integer | no | Page number |
| `per_page` | query | integer | no | Rows per page, 1–50 (default 10) |
| `date_from` | query | string | no | Y-m-d |
| `date_to` | query | string | no | Y-m-d |
| `search` | query | string | no | Number or service name |
| `sort_direction` | query | string | no | asc \| desc (default desc) |

```bash
curl -X GET 'https://claudeotp.com/api/v1/orders/history' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": [
        {
            "id": 6751431,
            "order_uuid": "FBTO1234567890NUM",
            "number": "6281234567890",
            "status": "completed",
            "price": 4720,
            "sms": [
                {
                    "code": "504374",
                    "text": "…",
                    "timestamp": "2026-10-09T08:16:02+07:00"
                }
            ]
        }
    ],
    "pagination": {
        "current_page": 1,
        "per_page": 10,
        "has_more_pages": false,
        "last_page": 1
    },
    "message": "Completed order history retrieved successfully"
}
```

### POST /orders/{id}/cancel

Cancel an order (refund). Allowed only before an SMS arrives, and usually only after a short minimum wait (`cancel_not_allowed_yet` until then). `DELETE /orders/{id}` does the same.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | string | yes | order_uuid or numeric order id |

```bash
curl -X POST 'https://claudeotp.com/api/v1/orders/FBTO1234567890NUM/cancel' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "message": "Order cancelled successfully",
    "data": null
}
```

Typical errors: `cancel_not_allowed_yet`, `order_already_cancelled`, `order_not_found`

### DELETE /orders/{id}

Cancel an order (alias)

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | string | yes | order_uuid or numeric order id |

```bash
curl -X DELETE 'https://claudeotp.com/api/v1/orders/FBTO1234567890NUM' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "message": "Order cancelled successfully",
    "data": null
}
```

### POST /orders/{id}/request-sms

Get another SMS on the same number. Asks the provider to deliver the next SMS to the same number — use it when the app sends a second code (first one expired or was mistyped). The order must still be active and have received at least one SMS. Trigger the resend in the target app, then keep polling GET /orders/{id}: the new SMS appears first in `messages` and in `latest_code`. Limited to one request per order every 20 seconds.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | string | yes | order_uuid or numeric order id |

```bash
curl -X POST 'https://claudeotp.com/api/v1/orders/FBTO1234567890NUM/request-sms' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "message": "Requested. Send the code again in the app — the new SMS will appear here."
}
```

Typical errors: `order_not_found`, `rate_limited`, `upstream_error`

### POST /orders/{id}/finish

Finish an order. Mark the order complete after you received the code. Frees your active-order slot.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | string | yes | order_uuid or numeric order id |

```bash
curl -X POST 'https://claudeotp.com/api/v1/orders/FBTO1234567890NUM/finish' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "message": "Order completed successfully",
    "data": null
}
```

### POST /orders/{id}/refund

Request a refund for a completed order. For a COMPLETED order whose code or number turned out to be unusable (code rejected, number already registered, etc.). Send as multipart/form-data with a screenshot of the problem. Rules: order completed within the last 3 days, one request per order, at most 1 request per day and 5 per 30 days per account. A reviewer decides; requests still pending after 72 hours are approved automatically and the price returns to your balance. Check `GET /refunds/eligible` first to see which orders qualify.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | string | yes | order_uuid or numeric order id |
| `reason` | body | string | yes | 10–1000 characters |
| `proof` | body | file | yes | Screenshot: jpg/png/webp, 50–8000 px, max 8 MB |

```bash
curl -X POST 'https://claudeotp.com/api/v1/orders/FBTO1234567890NUM/refund' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -F 'reason=WhatsApp says the number is already registered' \
  -F 'proof=@screenshot.png'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "refund": {
            "uuid": "3b7f…",
            "type": "vn",
            "order_id": 20325808,
            "order_uuid": "FBTO1234567890NUM",
            "amount": 945,
            "status": "pending",
            "reason": "…",
            "note": null,
            "created_at": "2026-10-09T08:00:00+07:00",
            "processed_at": null
        }
    },
    "message": "Your refund request has been submitted. Please wait for admin review."
}
```

Typical errors: `refund_not_allowed`, `validation_error`, `order_not_found`, `rate_limited`

## Refund requests

Manual refunds for completed number orders (POST /orders/{id}/refund) and complaints about SMM orders (POST /smm/orders/{uuid}/refund). Cancelled, expired and failed orders are refunded automatically — no request needed.

### GET /refunds/eligible

Orders you can request a refund for. `vn` = completed number orders that qualify right now, `smm` = SMM orders that can be complained about (with the claimable `amount`). `quota` applies to number orders only.

```bash
curl -X GET 'https://claudeotp.com/api/v1/refunds/eligible' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "vn": [
            {
                "id": 20325808,
                "order_uuid": "FBTO1234567890NUM",
                "amount": 945,
                "created_at": "2026-10-08T18:38:20+07:00"
            }
        ],
        "smm": [],
        "quota": {
            "daily_limit": 1,
            "daily_left": 1,
            "monthly_limit": 5,
            "monthly_left": 5
        },
        "rules": {
            "vn_max_order_age_days": 3,
            "smm_max_order_age_days": 14,
            "reason_min": 10,
            "vn_reason_max": 1000,
            "smm_reason_max": 480,
            "vn_proof_max_kb": 8192,
            "smm_proof_max_kb": 2048,
            "auto_approve_after_hours": 72
        }
    },
    "message": "OK"
}
```

### GET /refunds

Your refund requests. Newest first (max 100). `status`: pending | approved | rejected. `note` is the reviewer's note once decided.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `type` | query | string | no | vn \| smm |

```bash
curl -X GET 'https://claudeotp.com/api/v1/refunds' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "refunds": [
            {
                "uuid": "3b7f…",
                "type": "vn",
                "order_id": 20325808,
                "order_uuid": "FBTO1234567890NUM",
                "amount": 945,
                "status": "approved",
                "note": null,
                "created_at": "2026-10-09T08:00:00+07:00",
                "processed_at": "2026-10-09T10:12:00+07:00"
            }
        ]
    },
    "message": "OK"
}
```

## Social media services (SMM)

Followers, likes, views and more for Instagram, TikTok, YouTube, Facebook, Telegram and other platforms. Delivery is automatic; poll the order for progress.

### GET /smm/platforms

List platforms & service types

```bash
curl -X GET 'https://claudeotp.com/api/v1/smm/platforms' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "platforms": [
            {
                "key": "instagram",
                "label": "Instagram",
                "total": 870,
                "types": [
                    {
                        "type": "Followers",
                        "total": 197
                    },
                    {
                        "type": "Likes",
                        "total": 198
                    }
                ]
            }
        ]
    },
    "message": "OK"
}
```

### GET /smm/services

List services. Always filter by `platform` + `type`; unfiltered responses are large. `price_per_1000` is in IDR.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `platform` | query | string | no | Platform key from /smm/platforms |
| `type` | query | string | no | Service type within the platform |
| `category` | query | string | no | Legacy category name (overrides platform/type) |
| `sort` | query | string | no | quality (default) \| price_asc \| price_desc |

```bash
curl -X GET 'https://claudeotp.com/api/v1/smm/services' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "services": [
            {
                "id": 8112,
                "name": "Instagram Followers Indonesia [Refill 30 days]",
                "platform": "instagram",
                "service_type": "Followers",
                "type": "Default",
                "is_custom": false,
                "price_per_1000": 72000,
                "min": 50,
                "max": 50000,
                "refill": 0,
                "target_label": "Profile link / username",
                "completion_rate": 89,
                "refund_rate": 8,
                "is_recommended": false
            }
        ]
    },
    "message": "OK"
}
```

### GET /smm/services/{id}

Get one service. Current price and min/max — call right before ordering.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | integer | yes | Service id |

```bash
curl -X GET 'https://claudeotp.com/api/v1/smm/services/8112' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "id": 8112,
        "name": "…",
        "price_per_1000": 72000,
        "min": 50,
        "max": 50000
    },
    "message": "OK"
}
```

### POST /smm/quote

Calculate price. Preview the price. Does not charge your balance.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `service_id` | body | integer | yes | Service id |
| `quantity` | body | integer | no | Required for normal services |
| `custom_comments` | body | string | no | Custom-comment services only: one comment per line (quantity = number of lines) |

```bash
curl -X POST 'https://claudeotp.com/api/v1/smm/quote' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"service_id":8112,"quantity":1000}'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "quantity": 1000,
        "price": 72000
    },
    "message": "OK"
}
```

### POST /smm/orders

Place an SMM order

Accepts `Idempotency-Key` header.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `service_id` | body | integer | yes | Service id |
| `target` | body | string | yes | Link or username, as described by the service `target_label` |
| `quantity` | body | integer | no | Between the service min and max |
| `custom_comments` | body | string | no | Custom-comment services only, one per line |

```bash
curl -X POST 'https://claudeotp.com/api/v1/smm/orders' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -H 'Idempotency-Key: 2f6c1b9e-1d0a-4c55-9a4e-6b8f2c7d1e03' \
  -H 'Content-Type: application/json' \
  -d '{"service_id":8112,"target":"https://instagram.com/username","quantity":1000}'
```

Response (201):

```json
{
    "success": true,
    "data": {
        "order_uuid": "9f1c2f7a-6b41-4a0e-9d2e-1a2b3c4d5e6f",
        "service_id": 8112,
        "target": "https://instagram.com/username",
        "quantity": 1000,
        "price": 72000,
        "status": "pending"
    },
    "message": "Order placed successfully"
}
```

Typical errors: `insufficient_balance`, `validation_error`, `order_failed`

### GET /smm/orders

List SMM orders

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `page` | query | integer | no | Page number |
| `per_page` | query | integer | no | 1–100 (default 25) |
| `status` | query | string | no | pending \| processing \| in_progress \| completed \| partial \| canceled \| failed \| refunded |

```bash
curl -X GET 'https://claudeotp.com/api/v1/smm/orders' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "orders": [
            {
                "order_uuid": "9f1c2f7a-…",
                "status": "in_progress",
                "start_count": 1520,
                "remains": 400
            }
        ],
        "pagination": {
            "…": "…"
        }
    },
    "message": "OK"
}
```

### GET /smm/orders/{uuid}

Get one SMM order. Refreshed from the provider. `remains` = quantity not yet delivered; `refunded` = IDR returned for undelivered parts.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `uuid` | path | string | yes | order_uuid |

```bash
curl -X GET 'https://claudeotp.com/api/v1/smm/orders/9f1c2f7a-6b41-4a0e-9d2e-1a2b3c4d5e6f' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "order_uuid": "9f1c2f7a-…",
        "service_name": "…",
        "target": "…",
        "quantity": 1000,
        "price": 72000,
        "status": "completed",
        "start_count": 1520,
        "remains": 0,
        "refunded": 0,
        "created_at": "2026-10-09T08:00:00+07:00"
    },
    "message": "OK"
}
```

### POST /smm/orders/{uuid}/refund

Complain about an SMM order. For completed or partial orders from the last 14 days (e.g. followers dropped, not delivered). Send as multipart/form-data with a screenshot of the current count. The complaint is forwarded to the provider; if approved, the claimable amount (price minus anything already refunded) returns to your balance automatically. One complaint per order.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `uuid` | path | string | yes | order_uuid |
| `reason` | body | string | yes | 10–480 characters |
| `proof` | body | file | yes | Screenshot: jpg/png/webp, max 2 MB |

```bash
curl -X POST 'https://claudeotp.com/api/v1/smm/orders/9f1c2f7a-6b41-4a0e-9d2e-1a2b3c4d5e6f/refund' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -F 'reason=Followers dropped from 1,000 to 600' \
  -F 'proof=@screenshot.png'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "refund": {
            "uuid": "8c21…",
            "type": "smm",
            "order_uuid": "9f1c2f7a-…",
            "amount": 72000,
            "status": "pending"
        }
    },
    "message": "Complaint forwarded to the provider. Your balance is refunded automatically if it is approved."
}
```

Typical errors: `refund_not_allowed`, `validation_error`, `order_not_found`, `rate_limited`

## Gmail accounts

Ready-made Gmail accounts. Credentials are returned immediately and can be read again from your orders. Treat passwords as secrets.

### GET /gmail/stock

Stock & price

```bash
curl -X GET 'https://claudeotp.com/api/v1/gmail/stock' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "stock": 814,
        "sell_price": 5880,
        "max_qty": 50
    },
    "message": "OK"
}
```

### POST /gmail/orders

Buy Gmail accounts. Charged up front; anything that cannot be delivered is refunded automatically.

Accepts `Idempotency-Key` header.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `qty` | body | integer | yes | 1–50 (see max_qty) |

```bash
curl -X POST 'https://claudeotp.com/api/v1/gmail/orders' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -H 'Idempotency-Key: 2f6c1b9e-1d0a-4c55-9a4e-6b8f2c7d1e03' \
  -H 'Content-Type: application/json' \
  -d '{"qty":1}'
```

Response (201):

```json
{
    "success": true,
    "data": {
        "orders": [
            {
                "order_uuid": "c1d2…",
                "email": "someone123@gmail.com",
                "password": "••••••••",
                "price": 5880,
                "status": "completed",
                "refundable": true,
                "deadline_at": "2026-10-10T08:00:00+07:00"
            }
        ]
    },
    "message": "Purchase completed"
}
```

Typical errors: `insufficient_balance`, `out_of_stock`, `validation_error`

### GET /gmail/orders

List Gmail orders

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `page` | query | integer | no | Page number |
| `per_page` | query | integer | no | 1–100 |
| `status` | query | string | no | pending \| completed \| failed \| refund_pending \| refunded \| refund_rejected |

```bash
curl -X GET 'https://claudeotp.com/api/v1/gmail/orders' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "orders": [
            {
                "order_uuid": "c1d2…",
                "email": "someone123@gmail.com",
                "password": "••••••••",
                "status": "completed"
            }
        ]
    },
    "message": "OK"
}
```

### GET /gmail/orders/{uuid}

Get one Gmail order

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `uuid` | path | string | yes | order_uuid |

```bash
curl -X GET 'https://claudeotp.com/api/v1/gmail/orders/c1d2e3f4-…' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "order_uuid": "c1d2…",
        "email": "someone123@gmail.com",
        "password": "••••••••",
        "status": "completed",
        "refund_status": null,
        "refundable": true
    },
    "message": "OK"
}
```

### POST /gmail/orders/{uuid}/refund

File a refund dispute. Send as multipart/form-data while `refundable` is true. A screenshot proving the problem is required.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `uuid` | path | string | yes | order_uuid |
| `reason` | body | string | yes | 10–500 characters |
| `proof` | body | file | yes | Screenshot: jpg/png, max 4 MB |

```bash
curl -X POST 'https://claudeotp.com/api/v1/gmail/orders/c1d2e3f4-…/refund' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -F 'reason=Password is wrong, cannot sign in' \
  -F 'proof=@screenshot.png'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "refund_status": "pending"
    },
    "message": "OK"
}
```

### GET /gmail/orders/{uuid}/chat

Dispute chat link

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `uuid` | path | string | yes | order_uuid |

```bash
curl -X GET 'https://claudeotp.com/api/v1/gmail/orders/c1d2e3f4-…/chat' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "url": "https://…"
    },
    "message": "OK"
}
```

## Email rental

Rent an email address to receive one verification code. Cancel for a full refund if the code never arrives.

### GET /email-rental/suggestions

Popular target sites

```bash
curl -X GET 'https://claudeotp.com/api/v1/email-rental/suggestions' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "sites": [
            "tiktok.com",
            "facebook.com",
            "instagram.com",
            "x.com",
            "github.com"
        ]
    },
    "message": "OK"
}
```

### GET /email-rental/domains

Domains & prices for a site

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `site` | query | string | yes | Target site |

```bash
curl -X GET 'https://claudeotp.com/api/v1/email-rental/domains?site=tiktok.com' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "domains": [
            {
                "name": "outlook.com",
                "count": 740,
                "price": 140,
                "completed": 24500
            },
            {
                "name": "gmx.com",
                "count": 730628,
                "price": 124,
                "completed": 11752
            }
        ],
        "used_domains": []
    },
    "message": "OK"
}
```

### POST /email-rental/orders

Rent an address. Charges your balance and returns the address. Poll GET /email-rental/orders/{uuid} until `code` is filled.

Accepts `Idempotency-Key` header.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `site` | body | string | yes | Target site |
| `domain` | body | string | yes | Domain `name` from /email-rental/domains |

```bash
curl -X POST 'https://claudeotp.com/api/v1/email-rental/orders' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -H 'Idempotency-Key: 2f6c1b9e-1d0a-4c55-9a4e-6b8f2c7d1e03' \
  -H 'Content-Type: application/json' \
  -d '{"site":"tiktok.com","domain":"outlook.com"}'
```

Response (201):

```json
{
    "success": true,
    "data": {
        "order_uuid": "e5f6…",
        "site": "tiktok.com",
        "domain": "hotmail.com",
        "email": "abc123@outlook.com",
        "code": null,
        "price": 140,
        "status": "waiting",
        "cancellable": true
    },
    "message": "OK"
}
```

Typical errors: `insufficient_balance`, `service_unavailable`, `out_of_stock`

### GET /email-rental/orders

List rentals

```bash
curl -X GET 'https://claudeotp.com/api/v1/email-rental/orders' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "orders": [
            {
                "order_uuid": "e5f6…",
                "email": "abc123@hotmail.com",
                "code": "482913",
                "status": "completed"
            }
        ]
    },
    "message": "OK"
}
```

### GET /email-rental/orders/{uuid}

Get one rental (poll for the code). Checks the mailbox each call. Poll every 5–10 seconds.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `uuid` | path | string | yes | order_uuid |

```bash
curl -X GET 'https://claudeotp.com/api/v1/email-rental/orders/e5f6a7b8-…' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "order_uuid": "e5f6…",
        "email": "abc123@hotmail.com",
        "code": "482913",
        "message": "Your TikTok code is 482913",
        "status": "completed",
        "cancellable": false
    },
    "message": "OK"
}
```

### POST /email-rental/orders/{uuid}/cancel

Cancel a rental (refund)

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `uuid` | path | string | yes | order_uuid |

```bash
curl -X POST 'https://claudeotp.com/api/v1/email-rental/orders/e5f6a7b8-…/cancel' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "status": "canceled"
    },
    "message": "OK"
}
```

## WhatsApp Ready numbers

Numbers whose WhatsApp account is already active. Sign in with "Link with phone number / use your other phone": request a 6-digit code, enter it in WhatsApp, then confirm. Flow: ready → waiting_code → code_sent → completed. failed / canceled / refunded return the price to your balance.

### GET /wa-ready/info

Countries, prices & stock

```bash
curl -X GET 'https://claudeotp.com/api/v1/wa-ready/info' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "enabled": true,
        "countries": [
            {
                "iso": "ID",
                "name": "Indonesia",
                "price": 13200,
                "stock": 25
            }
        ]
    },
    "message": "OK"
}
```

### POST /wa-ready/orders

Buy a WhatsApp number

Accepts `Idempotency-Key` header.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `country` | body | string | yes | ISO 3166-1 alpha-2 from /wa-ready/info |

```bash
curl -X POST 'https://claudeotp.com/api/v1/wa-ready/orders' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -H 'Idempotency-Key: 2f6c1b9e-1d0a-4c55-9a4e-6b8f2c7d1e03' \
  -H 'Content-Type: application/json' \
  -d '{"country":"ID"}'
```

Response (201):

```json
{
    "success": true,
    "data": {
        "order": {
            "order_uuid": "3b9d…",
            "phone": "+6285860348151",
            "country": "ID",
            "price": 13200,
            "status": "ready"
        }
    },
    "message": "Number purchased"
}
```

Typical errors: `insufficient_balance`, `out_of_stock`, `provider_unavailable`

### GET /wa-ready/orders

List WhatsApp orders

```bash
curl -X GET 'https://claudeotp.com/api/v1/wa-ready/orders' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "orders": [
            {
                "order_uuid": "3b9d…",
                "phone": "+6285860348151",
                "status": "completed"
            }
        ]
    },
    "message": "OK"
}
```

### GET /wa-ready/orders/{uuid}

Get order status (poll for the code). Poll every 3–5 seconds while `waiting_code`. Always use `latest_code`. Allowed actions are given by the `can_*` flags.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `uuid` | path | string | yes | order_uuid |

```bash
curl -X GET 'https://claudeotp.com/api/v1/wa-ready/orders/3b9d…' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "order": {
            "order_uuid": "3b9d…",
            "phone": "+6285860348151",
            "status": "code_sent",
            "latest_code": "482913",
            "can_confirm": true,
            "can_cancel": false,
            "can_dispute": true
        }
    },
    "message": "OK"
}
```

### POST /wa-ready/orders/{uuid}/request-code

Request the 6-digit code. Start the "link with phone number" flow in WhatsApp first, then call this.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `uuid` | path | string | yes | order_uuid |

```bash
curl -X POST 'https://claudeotp.com/api/v1/wa-ready/orders/3b9d…/request-code' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "order": {
            "status": "waiting_code"
        }
    },
    "message": "OK"
}
```

### POST /wa-ready/orders/{uuid}/confirm

Confirm successful sign-in

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `uuid` | path | string | yes | order_uuid |

```bash
curl -X POST 'https://claudeotp.com/api/v1/wa-ready/orders/3b9d…/confirm' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "order": {
            "status": "completed"
        }
    },
    "message": "OK"
}
```

### POST /wa-ready/orders/{uuid}/cancel

Cancel (refund). Only while `can_cancel` is true (before a code was received).

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `uuid` | path | string | yes | order_uuid |

```bash
curl -X POST 'https://claudeotp.com/api/v1/wa-ready/orders/3b9d…/cancel' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "order": {
            "status": "canceled"
        }
    },
    "message": "OK"
}
```

### POST /wa-ready/orders/{uuid}/dispute

File a complaint (refund). multipart/form-data, only while `can_dispute`. Approved → refunded; follow replies in the order `messages`.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `uuid` | path | string | yes | order_uuid |
| `reason` | body | string | yes | 5–1000 characters |
| `image` | body | file | yes | Screenshot: jpg/png/webp, max 4 MB |

```bash
curl -X POST 'https://claudeotp.com/api/v1/wa-ready/orders/3b9d…/dispute' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -F 'reason=WhatsApp rejected the latest code' \
  -F 'image=@screenshot.png'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "order": {
            "dispute_status": "pending"
        }
    },
    "message": "OK"
}
```

### POST /wa-ready/orders/{uuid}/message

Reply in the complaint thread

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `uuid` | path | string | yes | order_uuid |
| `body` | body | string | yes | Up to 1000 characters |

```bash
curl -X POST 'https://claudeotp.com/api/v1/wa-ready/orders/3b9d…/message' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"body":"Screenshot attached above"}'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "order": {
            "…": "…"
        }
    },
    "message": "OK"
}
```

## Deposits & transactions

Top up your balance from code. Payment instructions (QR / virtual account / checkout URL) come back in the deposit response.

### GET /payment-methods

List payment methods

```bash
curl -X GET 'https://claudeotp.com/api/v1/payment-methods' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": [
        {
            "id": 12,
            "name": "Qris Asia",
            "category_name": "Payment Gateway",
            "expiration_time": 5
        }
    ],
    "message": "OK"
}
```

### POST /deposits

Create a deposit (IDR). Returns the transaction with payment instructions (QR image as `qr_code_base64` or a `payment_url`). Poll GET /transactions/{uniqcode} for the status.

Accepts `Idempotency-Key` header.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `amount` | body | integer | yes | IDR, minimum 10000 |
| `method` | body | integer | yes | Payment method id from /payment-methods |

```bash
curl -X POST 'https://claudeotp.com/api/v1/deposits' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -H 'Idempotency-Key: 2f6c1b9e-1d0a-4c55-9a4e-6b8f2c7d1e03' \
  -H 'Content-Type: application/json' \
  -d '{"amount":50000,"method":12}'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "uniqcode_tx": "TX…",
        "amount": 50000,
        "total_amount": 50123,
        "status": "pending",
        "qr_code_base64": "iVBOR…",
        "expires_at_iso": "2026-10-09T08:05:00+07:00"
    },
    "message": "OK"
}
```

### POST /deposits/crypto

Create a crypto deposit (USD)

Accepts `Idempotency-Key` header.

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `amount` | body | number | yes | USD, 1–10000 |

```bash
curl -X POST 'https://claudeotp.com/api/v1/deposits/crypto' \
  -H 'X-API-Key: YOUR_API_KEY' \
  -H 'Idempotency-Key: 2f6c1b9e-1d0a-4c55-9a4e-6b8f2c7d1e03' \
  -H 'Content-Type: application/json' \
  -d '{"amount":10}'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "checkout_url": "https://…"
    },
    "message": "OK"
}
```

### GET /transactions

List deposits

```bash
curl -X GET 'https://claudeotp.com/api/v1/transactions' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "transactions": [
            {
                "uniqcode_tx": "TX…",
                "type": "deposit",
                "amount": 50000,
                "fee": 0,
                "total_amount": 50123,
                "status": "success",
                "status_label": "Success",
                "payment_method": {
                    "…": "…"
                },
                "payment_url": null,
                "created_at_iso": "2026-10-09T08:00:00+07:00"
            }
        ],
        "pagination": {
            "…": "…"
        }
    },
    "message": "OK"
}
```

### GET /transactions/{uniqcode}

Get one deposit

| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `uniqcode` | path | string | yes | `uniqcode_tx` from the deposit / transaction list |

```bash
curl -X GET 'https://claudeotp.com/api/v1/transactions/TX…' \
  -H 'X-API-Key: YOUR_API_KEY'
```

Response (200):

```json
{
    "success": true,
    "data": {
        "uniqcode_tx": "TX…",
        "amount": 50000,
        "total_amount": 50123,
        "status": "pending",
        "expires_in_seconds": 290,
        "qr_code_base64": "iVBOR…",
        "payment_url": null
    },
    "message": "OK"
}
```

## Error codes

Error response: `{"success": false, "message": "...", "error_code": "...", "request_id": "..."}`

| error_code | HTTP | Meaning |
|---|---|---|
| `unauthenticated` | 401 | No API key was sent. |
| `invalid_api_key` | 401 | The API key is wrong or the account is disabled. |
| `api_key_wrong_domain` | 401 | The key belongs to a different site. Use the site where you registered. |
| `validation_error` | 422 | A parameter is missing or invalid. Details per field are in `errors`. |
| `insufficient_balance` | 422 | Not enough balance. Top up and retry. |
| `out_of_stock` | 422 | No stock for this choice right now. Pick another country/server or retry in a few minutes. |
| `service_unavailable` | 422 | The service or target site is not supported right now. |
| `order_failed` | 422 | The provider rejected the order. Nothing was charged (or it was refunded). |
| `cancel_not_allowed_yet` | 422 | The order cannot be cancelled yet. Retry shortly. |
| `order_already_cancelled` | 422 | The order was already cancelled. |
| `provider_unavailable` | 422 | The upstream provider is temporarily unavailable or restricted. Retry later. |
| `upstream_error` | 422 | Any other failure reported by the provider. Read `message`. |
| `idempotency_key_reused` | 422 | This Idempotency-Key was already used with different parameters. |
| `refund_not_allowed` | 422 | The order does not qualify (too old, not completed, already requested) or your refund limit is reached. Read `message`. |
| `order_not_found` | 404 | No such order for this API key. |
| `not_found` | 404 | Unknown endpoint or resource. |
| `product_unavailable` | 404 | This product is not offered on this site. |
| `idempotency_in_progress` | 409 | The first request with this Idempotency-Key is still running. Retry in a few seconds. |
| `rate_limited` | 429 | Too many requests. Wait and retry. |
| `server_error` | 500 | Unexpected error on our side. Retry; contact support with the request_id if it persists. |
