# BulkMail API v2
Web reference: https://bulkmail.shop/v2-docs · Download: [OpenAPI 3.1 (YAML)](https://bulkmail.shop/v2-docs/openapi.yaml) · [Postman collection](https://bulkmail.shop/v2-docs/postman.json) · [Markdown](https://bulkmail.shop/v2-docs/api-v2.md)
REST API for buying email accounts and other digital goods on BulkMail.
**Base URL** `https://bulkmail.shop/api/v2`
**Authentication.** Create a key on your dashboard (API Keys page) and send it on every request as the `X-API-Key` header. The `api_key` query parameter also works but puts the key in logs, so prefer the header. Public endpoints work without a key; with one they show your own prices.
**Responses.** JSON in an envelope: `{"success": true, "data": …}`, or `{"success": false, "error": "…"}`. Validation errors (422) add `errors`, a map of field to messages. Lists are paginated with `page` and `per_page` (max 100) and return `meta`.
**Unknown paths** answer with a JSON 404: `{"success": false, "error": "No endpoint for GET /api/v2/nope"}`.
**Formats.** Dates are ISO 8601 in UTC (`2026-10-11T14:32:46.000000Z`). Money is USD as a number with up to 8 decimals. Ids are integers.
Examples are real responses captured on 2026-10-11, with the account holder's details and delivered account lines replaced by samples. Long lists are cut to their first 3 items.
## Endpoints
- **Account**: [`GET /user/profile`](#get-user-profile), [`PUT /user/profile`](#put-user-profile), [`POST /user/password`](#post-user-password), [`GET /user/dashboard`](#get-user-dashboard), [`DELETE /user/account`](#delete-user-account)
- **Products**: [`GET /products`](#get-products), [`GET /products/{id}`](#get-products-id), [`POST /products/{id}/calculate-price`](#post-products-id-calculate-price), [`GET /tabs`](#get-tabs)
- **Stock**: [`GET /stock`](#get-stock), [`GET /stock/{id}`](#get-stock-id), [`GET /stock/check`](#get-stock-check), [`GET /stock/categories`](#get-stock-categories)
- **Orders**: [`GET /orders`](#get-orders), [`GET /orders/{id}`](#get-orders-id), [`POST /orders`](#post-orders), [`POST /orders/{id}/cancel`](#post-orders-id-cancel), [`GET /orders/{id}/export`](#get-orders-id-export)
- **Wallet**: [`GET /wallet/balance`](#get-wallet-balance), [`GET /wallet/transactions`](#get-wallet-transactions), [`POST /wallet/deposit`](#post-wallet-deposit), [`GET /wallet/deposits`](#get-wallet-deposits), [`GET /wallet/deposits/{id}`](#get-wallet-deposits-id)
- **Purchases**: [`GET /purchases`](#get-purchases), [`GET /purchases/{id}`](#get-purchases-id)
- **API Keys**: [`GET /api-keys`](#get-api-keys), [`POST /api-keys`](#post-api-keys), [`DELETE /api-keys/{id}`](#delete-api-keys-id)
## Account
Your profile, password and dashboard.
### Get your profile
`GET /api/v2/user/profile`
**Auth:** API key
Your account details and current balance (USD).
```bash
curl -X GET "https://bulkmail.shop/api/v2/user/profile" \
-H "X-API-Key: YOUR_API_KEY"
```
**200 OK** — Profile
```json
{
"success": true,
"data": {
"id": 1001,
"name": "Demo User",
"email": "demo@example.com",
"balance": 339.60453503,
"status": "active",
"email_verified_at": "2026-02-21T05:56:10.000000Z",
"created_at": "2026-02-21T05:56:10.000000Z"
}
}
```
**401 Missing or invalid API key** — No or invalid key
```json
{
"success": false,
"error": "Invalid or missing authentication"
}
```
### Update your profile
`PUT /api/v2/user/profile`
**Auth:** API key
Change your name and/or email. Fields you leave out keep their current value.
| Body field | Type | Required | Description |
|---|---|---|---|
| `name` | string | no | New display name. |
| `email` | string | no | New email; must not belong to another account. |
```bash
curl -X PUT "https://bulkmail.shop/api/v2/user/profile" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Demo User"}'
```
**200 OK** — Updated *(illustrative)*
```json
{
"success": true,
"message": "Profile updated successfully",
"data": {
"id": 1001,
"name": "Demo User",
"email": "demo@example.com",
"balance": 125.5,
"status": "active",
"email_verified_at": "2026-02-21T05:56:10.000000Z",
"created_at": "2026-02-21T05:56:10.000000Z"
}
}
```
**422 Validation failed or cannot be fulfilled** — Invalid email
```json
{
"success": false,
"error": "Validation failed",
"errors": {
"email": [
"Valid email is required."
]
}
}
```
### Change your password
`POST /api/v2/user/password`
**Auth:** API key
| Body field | Type | Required | Description |
|---|---|---|---|
| `current_password` | string | yes | |
| `new_password` | string | yes | At least 8 characters. |
| `confirm_password` | string | yes | Must equal new_password. |
```bash
curl -X POST "https://bulkmail.shop/api/v2/user/password" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"current_password": "old-password", "new_password": "new-password-123", "confirm_password": "new-password-123"}'
```
**200 OK** — Changed *(illustrative)*
```json
{
"success": true,
"message": "Password changed successfully"
}
```
**422 Validation failed or cannot be fulfilled** — Wrong current password
```json
{
"success": false,
"error": "Validation failed",
"errors": {
"current_password": [
"Current password is incorrect."
],
"new_password": [
"New password must be at least 8 characters."
],
"confirm_password": [
"Passwords do not match."
]
}
}
```
### Get your dashboard
`GET /api/v2/user/dashboard`
**Auth:** API key
Account, totals, and your 5 most recent orders and transactions.
```bash
curl -X GET "https://bulkmail.shop/api/v2/user/dashboard" \
-H "X-API-Key: YOUR_API_KEY"
```
**200 OK** — Dashboard
```json
{
"success": true,
"data": {
"user": {
"id": 1001,
"name": "Demo User",
"email": "demo@example.com",
"balance": 339.60453503,
"status": "active",
"created_at": "2026-02-21T05:56:10.000000Z"
},
"stats": {
"total_orders": 3656,
"total_spent": 560.39546497,
"purchased_items": 14574
},
"recent_orders": [
{
"id": 1232875,
"product_id": 13,
"quantity": 2,
"total_amount": 0.02394032,
"status": "completed",
"created_at": "2026-10-11T16:58:00.000000Z"
},
{
"id": 1232770,
"product_id": 13,
"quantity": 1,
"total_amount": 0.01197016,
"status": "completed",
"created_at": "2026-10-11T16:30:01.000000Z"
},
{
"id": 1232374,
"product_id": 970,
"quantity": 1,
"total_amount": 0.00455153,
"status": "completed",
"created_at": "2026-10-11T14:32:46.000000Z"
}
],
"recent_transactions": [
{
"id": 1247991,
"type": "purchase",
"amount": 0.02394032,
"direction": "out",
"signed_amount": -0.02394032,
"balance_after": 339.60453503,
"created_at": "2026-10-11T16:58:00.000000Z"
},
{
"id": 1247879,
"type": "purchase",
"amount": 0.01197016,
"direction": "out",
"signed_amount": -0.01197016,
"balance_after": 339.62847535,
"created_at": "2026-10-11T16:30:01.000000Z"
},
{
"id": 1247463,
"type": "purchase",
"amount": 0.00455153,
"direction": "out",
"signed_amount": -0.00455153,
"balance_after": 339.64044551,
"created_at": "2026-10-11T14:32:46.000000Z"
}
]
}
}
```
### Delete your account
`DELETE /api/v2/user/account`
**Auth:** API key
Closes the account. Requires your password. This cannot be undone through the API.
| Body field | Type | Required | Description |
|---|---|---|---|
| `password` | string | yes | |
```bash
curl -X DELETE "https://bulkmail.shop/api/v2/user/account" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"password": "your-password"}'
```
**200 OK** — Deleted *(illustrative)*
```json
{
"success": true,
"message": "Account deleted successfully"
}
```
**422 Validation failed or cannot be fulfilled** — Wrong password
```json
{
"success": false,
"error": "Validation failed",
"errors": {
"password": [
"Incorrect password."
]
}
}
```
## Products
The catalogue and prices. Public; send your key to see your own prices.
### List products
`GET /api/v2/products`
**Auth:** Public (API key optional)
The catalogue, paginated. Send your API key to get your own prices: pricing flags appear only when they apply.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `page` | query | integer | no | Page number, from 1. |
| `per_page` | query | integer | no | Items per page, 1-100 (default 20). |
| `search` | query | string | no | Text to find in name, SKU or description. Alias: q. |
| `tab_id` | query | integer | no | Only products in this tab (see /tabs). |
| `in_stock` | query | boolean | no | true = in stock only, false = out of stock only. |
| `sort` | query | string (name\|price\|stock_quantity\|created_at) | no | Sort field (default name). |
| `order` | query | string (asc\|desc) | no | Sort direction (default asc). |
```bash
curl -X GET "https://bulkmail.shop/api/v2/products?per_page=2"
```
**200 OK** — With your key
```json
{
"success": true,
"data": [
{
"id": 911,
"name": "✔️ live 2 minute xxx@RanDom",
"sku": "LIVE2MINUTEX",
"tab_id": 26,
"price": 0.00253132,
"base_price": 0.00260961,
"user_discount_applied": true,
"user_discount_percent": 3,
"stock_quantity": 0,
"in_stock": false,
"bulk_pricing_enabled": false,
"image_url": null,
"image_type": null,
"created_at": "2026-09-19T15:06:13.000000Z",
"is_pack": false,
"allowed_quantities": null,
"pack_options": null,
"description": "✔️ live 2 minute xxx@RanDom",
"description_format": "text",
"description_text": "✔️ live 2 minute xxx@RanDom",
"description_html": null
},
{
"id": 906,
"name": "10 Minutes – 99 per [ID 180] ----No",
"sku": "10PHT99PERID",
"tab_id": 26,
"price": 0.00353677,
"base_price": 0.00364615,
"user_discount_applied": true,
"user_discount_percent": 3,
"stock_quantity": 0,
"in_stock": false,
"bulk_pricing_enabled": false,
"image_url": null,
"image_type": null,
"created_at": "2026-09-13T18:07:05.000000Z",
"is_pack": false,
"allowed_quantities": null,
"pack_options": null,
"description": "10 Minutes – 99 /Time [ID 180] ----No",
"description_format": "text",
"description_text": "10 Minutes – 99 /Time [ID 180] ----No",
"description_html": null
}
],
"meta": {
"current_page": 1,
"per_page": 2,
"total": 427,
"total_pages": 214
}
}
```
**200 OK** — Search
```json
{
"success": true,
"data": [
{
"id": 814,
"name": "Airbnb Gmail",
"sku": "AIRBNBGMA-3013",
"tab_id": 8,
"price": 0.035696,
"base_price": 0.0368,
"user_discount_applied": true,
"user_discount_percent": 3,
"stock_quantity": 5041,
"in_stock": true,
"bulk_pricing_enabled": false,
"image_url": null,
"image_type": null,
"created_at": "2026-08-15T06:58:01.000000Z",
"is_pack": false,
"allowed_quantities": null,
"pack_options": null,
"description": "Gmail API - Receive any Airbnb email message",
"description_format": "text",
"description_text": "Gmail API - Receive any Airbnb email message",
"description_html": null
},
{
"id": 810,
"name": "Alibaba Gmail",
"sku": "ALIBABAGM-39",
"tab_id": 8,
"price": 0.0591215,
"base_price": 0.06095,
"user_discount_applied": true,
"user_discount_percent": 3,
"stock_quantity": 5002,
"in_stock": true,
"bulk_pricing_enabled": false,
"image_url": null,
"image_type": null,
"created_at": "2026-08-15T06:58:01.000000Z",
"is_pack": false,
"allowed_quantities": null,
"pack_options": null,
"description": "Gmail API - Receive any Alibaba email message",
"description_format": "text",
"description_text": "Gmail API - Receive any Alibaba email message",
"description_html": null
}
],
"meta": {
"current_page": 1,
"per_page": 2,
"total": 211,
"total_pages": 106
}
}
```
**200 OK** — Without a key
```json
{
"success": true,
"data": [
{
"id": 911,
"name": "✔️ live 2 minute xxx@RanDom",
"sku": "LIVE2MINUTEX",
"tab_id": 26,
"price": 0.00260961,
"base_price": 0.00260961,
"stock_quantity": 0,
"in_stock": false,
"bulk_pricing_enabled": false,
"image_url": null,
"image_type": null,
"created_at": "2026-09-19T15:06:13.000000Z",
"is_pack": false,
"allowed_quantities": null,
"pack_options": null,
"description": "✔️ live 2 minute xxx@RanDom",
"description_format": "text",
"description_text": "✔️ live 2 minute xxx@RanDom",
"description_html": null
},
{
"id": 906,
"name": "10 Minutes – 99 per [ID 180] ----No",
"sku": "10PHT99PERID",
"tab_id": 26,
"price": 0.00364615,
"base_price": 0.00364615,
"stock_quantity": 0,
"in_stock": false,
"bulk_pricing_enabled": false,
"image_url": null,
"image_type": null,
"created_at": "2026-09-13T18:07:05.000000Z",
"is_pack": false,
"allowed_quantities": null,
"pack_options": null,
"description": "10 Minutes – 99 /Time [ID 180] ----No",
"description_format": "text",
"description_text": "10 Minutes – 99 /Time [ID 180] ----No",
"description_html": null
}
],
"meta": {
"current_page": 1,
"per_page": 2,
"total": 427,
"total_pages": 214
}
}
```
### Get a product
`GET /api/v2/products/{id}`
**Auth:** Public (API key optional)
One product with its features, and bulk_pricing_tiers when bulk pricing applies to you.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | integer | yes | Product id. |
```bash
curl -X GET "https://bulkmail.shop/api/v2/products/986"
```
**200 OK** — Product
```json
{
"success": true,
"data": {
"id": 986,
"name": "1h - 12h edu.pl",
"sku": "1H12HEDUPL",
"tab_id": 42,
"price": 0.02571542,
"base_price": 0.02651074,
"user_discount_applied": true,
"user_discount_percent": 3,
"stock_quantity": 1022,
"in_stock": true,
"bulk_pricing_enabled": false,
"image_url": null,
"image_type": null,
"created_at": "2026-10-04T18:20:15.000000Z",
"is_pack": false,
"allowed_quantities": null,
"pack_options": null,
"description": "1h - 12h edu.pl",
"description_format": "text",
"description_text": "1h - 12h edu.pl",
"description_html": null,
"features": []
}
}
```
**200 OK** — Pack product with HTML description
```json
{
"success": true,
"data": {
"id": 1003,
"name": "Custom Domain Gmail | 24H | Pesviv.com",
"sku": "CUSTOMDOMAIN",
"tab_id": 26,
"price": 0.01455,
"base_price": 0.015,
"user_discount_applied": true,
"user_discount_percent": 3,
"stock_quantity": 3594,
"in_stock": true,
"bulk_pricing_enabled": false,
"image_url": null,
"image_type": null,
"created_at": "2026-10-11T10:31:09.000000Z",
"is_pack": true,
"allowed_quantities": [
12,
25,
35,
45,
65,
85,
95,
135,
405,
540,
675,
1350
],
"pack_options": [
{
"quantity": 12,
"unit_price": 0.01455,
"total_price": 0.1746,
"available": true
},
{
"quantity": 25,
"unit_price": 0.01455,
"total_price": 0.36375,
"available": true
},
{
"quantity": 35,
"unit_price": 0.01455,
"total_price": 0.50925,
"available": true
}
],
"description": "
Premium custom-domain Gmail accounts with full Gmail / Google Workspace inbox access, suitable for verification, platform sign-ups, testing, and other operational use.
- Type: Custom Gmail Domain Account
- Domain: Random Custom Domain
- Access: Full Gmail Inbox Access Not Guaranteed.
- Delivery: Instant Automated Delivery
- Duration: As mentioned in the product title
Important Notice
- Domain names are randomly assigned and may vary between orders. We strongly recommend purchasing a small quantity first and testing compatibility with your software, proxy, or intended platform before placing a bulk order.
- These are temporary accounts. Do not store critical or sensitive information. Use responsibly and in accordance with the target platform's policies.
",
"description_format": "html",
"description_text": "Premium custom-domain Gmail accounts with full Gmail / Google Workspace inbox access, suitable for verification, platform sign-ups, testing, and other operational use. Type: Custom Gmail Domain Account Domain: Random Custom Domain Access: Full Gmail Inbox Access Not Guaranteed. Delivery: Instant Automated Delivery Duration: As mentioned in the product title Important Notice Domain names are randomly assigned and may vary between orders. We strongly recommend purchasing a small quantity first and testing compatibility with your software, proxy, or intended platform before placing a bulk order. These are temporary accounts. Do not store critical or sensitive information. Use responsibly and in accordance with the target platform's policies.",
"description_html": "Premium custom-domain Gmail accounts with full Gmail / Google Workspace inbox access, suitable for verification, platform sign-ups, testing, and other operational use.
- Type: Custom Gmail Domain Account
- Domain: Random Custom Domain
- Access: Full Gmail Inbox Access Not Guaranteed.
- Delivery: Instant Automated Delivery
- Duration: As mentioned in the product title
Important Notice
- Domain names are randomly assigned and may vary between orders. We strongly recommend purchasing a small quantity first and testing compatibility with your software, proxy, or intended platform before placing a bulk order.
- These are temporary accounts. Do not store critical or sensitive information. Use responsibly and in accordance with the target platform's policies.
",
"features": []
}
}
```
**404 Not found** — Not found
```json
{
"success": false,
"error": "Product not found"
}
```
### Calculate a price
`POST /api/v2/products/{id}/calculate-price`
**Auth:** Public (API key optional)
What a quantity would cost you. Pack products accept only their allowed_quantities.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | integer | yes | Product id. |
| Body field | Type | Required | Description |
|---|---|---|---|
| `quantity` | integer | yes | 1 or more; for pack products one of allowed_quantities. |
```bash
curl -X POST "https://bulkmail.shop/api/v2/products/986/calculate-price" \
-H "Content-Type: application/json" \
-d '{"quantity": 10}'
```
**200 OK** — With your key
```json
{
"success": true,
"data": {
"product_id": 986,
"quantity": 10,
"base_price": 0.02651074,
"applied_price": 0.02571542,
"total_amount": 0.25715,
"discount_percentage": 3,
"user_discount_applied": true,
"user_discount_percent": 3,
"price_before_user_discount": 0.02651
}
}
```
**200 OK** — Without a key
```json
{
"success": true,
"data": {
"product_id": 986,
"quantity": 10,
"base_price": 0.02651074,
"applied_price": 0.02651074,
"total_amount": 0.26511
}
}
```
**400 Bad request** — Invalid pack size
```json
{
"success": false,
"error": "This product is sold in packs only. Please choose one of these quantities: 12, 25, 35, 45, 65, 85, 95, 135, 405, 540, 675, 1350.",
"errors": {
"code": "INVALID_PACK_SIZE",
"allowed_quantities": [
12,
25,
35,
45,
65,
85,
95,
135,
405,
540,
675,
1350
]
}
}
```
**400 Bad request** — Quantity 0
```json
{
"success": false,
"error": "Quantity must be at least 1"
}
```
### List tabs (categories)
`GET /api/v2/tabs`
**Auth:** Public (API key optional)
Storefront tabs in display order. A product's tab_id points here.
```bash
curl -X GET "https://bulkmail.shop/api/v2/tabs"
```
**200 OK** — Tabs
```json
{
"success": true,
"data": [
{
"id": 7,
"name": "All",
"slug": "all",
"title": "Popular Shop",
"description": "",
"logo_url": null,
"sort_order": -2,
"product_count": 0
},
{
"id": 6,
"name": "Hotmail Outlook ",
"slug": "hotmail-outlook",
"title": "Hotmail Outlook ",
"description": "",
"logo_url": "https://bulkmail.shop/uploads/icons/icon_187.webp",
"sort_order": -1,
"product_count": 34
},
{
"id": 4,
"name": "Outlook Domain Country ",
"slug": "outlook-domain-country",
"title": "Outlook Domain Country ",
"description": "",
"logo_url": "https://bulkmail.shop/uploads/icons/icon_136.webp",
"sort_order": 0,
"product_count": 30
}
]
}
```
## Stock
Live stock figures. Public.
### Stock of all products
`GET /api/v2/stock`
**Auth:** Public (API key optional)
Every product on sale with its stock (not paginated). last_updated is when that figure was refreshed.
```bash
curl -X GET "https://bulkmail.shop/api/v2/stock"
```
**200 OK** — All products
```json
{
"success": true,
"data": {
"products": [
{
"id": 911,
"name": "✔️ live 2 minute xxx@RanDom",
"sku": "LIVE2MINUTEX",
"stock": 0,
"in_stock": false,
"is_pack": false,
"allowed_quantities": null,
"last_updated": "2026-10-11T17:33:03.000000Z"
},
{
"id": 906,
"name": "10 Minutes – 99 per [ID 180] ----No",
"sku": "10PHT99PERID",
"stock": 0,
"in_stock": false,
"is_pack": false,
"allowed_quantities": null,
"last_updated": "2026-10-11T17:33:03.000000Z"
},
{
"id": 986,
"name": "1h - 12h edu.pl",
"sku": "1H12HEDUPL",
"stock": 1022,
"in_stock": true,
"is_pack": false,
"allowed_quantities": null,
"last_updated": "2026-10-11T17:31:29.000000Z"
}
],
"total_products": 427,
"timestamp": "2026-10-11T17:33:03.000000Z"
}
}
```
### Stock of one product
`GET /api/v2/stock/{id}`
**Auth:** Public (API key optional)
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | integer | yes | Product id. |
```bash
curl -X GET "https://bulkmail.shop/api/v2/stock/986"
```
**200 OK** — Product
```json
{
"success": true,
"data": {
"id": 986,
"name": "1h - 12h edu.pl",
"sku": "1H12HEDUPL",
"stock": 1022,
"in_stock": true,
"is_pack": false,
"allowed_quantities": null,
"last_updated": "2026-10-11T17:31:29.000000Z"
}
}
```
**404 Not found** — Not found
```json
{
"success": false,
"error": "Product not found"
}
```
### Stock of several products
`GET /api/v2/stock/check`
**Auth:** Public (API key optional)
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `ids` | query | string | yes | Comma-separated product ids, up to 50. |
```bash
curl -X GET "https://bulkmail.shop/api/v2/stock/check?ids=986,1003,99999999"
```
**200 OK** — Three ids, one unknown
```json
{
"success": true,
"data": {
"products": [
{
"id": 986,
"name": "1h - 12h edu.pl",
"stock": 1022,
"in_stock": true,
"is_pack": false,
"allowed_quantities": null
},
{
"id": 1003,
"name": "Custom Domain Gmail | 24H | Pesviv.com",
"stock": 3594,
"in_stock": true,
"is_pack": true,
"allowed_quantities": [
12,
25,
35,
45,
65,
85,
95,
135,
405,
540,
675,
1350
]
},
{
"id": 99999999,
"error": "Product not found",
"stock": 0,
"in_stock": false
}
],
"timestamp": "2026-10-11T17:33:03.000000Z"
}
}
```
**400 Bad request** — Missing ids
```json
{
"success": false,
"error": "Product IDs required"
}
```
### Stock per category
`GET /api/v2/stock/categories`
**Auth:** Public (API key optional)
Stock totals per storefront tab, in /tabs order. Tabs with nothing on sale are left out.
```bash
curl -X GET "https://bulkmail.shop/api/v2/stock/categories"
```
**200 OK** — Categories
```json
{
"success": true,
"data": {
"categories": [
{
"tab_id": 6,
"category": "Hotmail Outlook ",
"slug": "hotmail-outlook",
"products": 34,
"total_stock": 926861,
"in_stock_products": 18
},
{
"tab_id": 4,
"category": "Outlook Domain Country ",
"slug": "outlook-domain-country",
"products": 30,
"total_stock": 412677,
"in_stock_products": 26
},
{
"tab_id": 9,
"category": "Short Live Mail",
"slug": "short-live-mail",
"products": 3,
"total_stock": 0,
"in_stock_products": 0
}
],
"timestamp": "2026-10-11T17:33:04.000000Z"
}
}
```
## Orders
Buy products and read your orders.
### List your orders
`GET /api/v2/orders`
**Auth:** API key
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `page` | query | integer | no | Page number, from 1. |
| `per_page` | query | integer | no | Items per page, 1-100 (default 20). |
| `status` | query | string (pending\|completed\|cancelled\|refunded) | no | |
| `date_from` | query | string | no | YYYY-MM-DD |
| `date_to` | query | string | no | YYYY-MM-DD (inclusive) |
```bash
curl -X GET "https://bulkmail.shop/api/v2/orders?per_page=2" \
-H "X-API-Key: YOUR_API_KEY"
```
**200 OK** — Latest orders
```json
{
"success": true,
"data": [
{
"id": 1232875,
"product_id": 13,
"product_name": "Gmail Edu domain rental for 24 hours (.us domain) with Gmail",
"quantity": 2,
"unit_price": 0.01197016,
"total_amount": 0.02394032,
"status": "completed",
"created_at": "2026-10-11T16:58:00.000000Z"
},
{
"id": 1232770,
"product_id": 13,
"product_name": "Gmail Edu domain rental for 24 hours (.us domain) with Gmail",
"quantity": 1,
"unit_price": 0.01197016,
"total_amount": 0.01197016,
"status": "completed",
"created_at": "2026-10-11T16:30:01.000000Z"
}
],
"meta": {
"current_page": 1,
"per_page": 2,
"total": 3656,
"total_pages": 1828
}
}
```
### Get an order
`GET /api/v2/orders/{id}`
**Auth:** API key
The price you paid (unit_price, subtotal, discount_amount, total_amount) and the delivered lines. product.price is today's price.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | integer | yes | Order id. |
```bash
curl -X GET "https://bulkmail.shop/api/v2/orders/1232875" \
-H "X-API-Key: YOUR_API_KEY"
```
**200 OK** — Order
```json
{
"success": true,
"data": {
"id": 1232875,
"product_id": 13,
"product_name": "Gmail Edu domain rental for 24 hours (.us domain) with Gmail",
"quantity": 2,
"unit_price": 0.01197016,
"subtotal": 0.02394032,
"discount_amount": 0,
"reward_code": null,
"total_amount": 0.02394032,
"status": "completed",
"created_at": "2026-10-11T16:58:00.000000Z",
"updated_at": "2026-10-11T16:58:00.000000Z",
"product": {
"id": 13,
"name": "Gmail Edu domain rental for 24 hours (.us domain) with Gmail",
"sku": "EDUMAIL-0029",
"price": 0.01234037
},
"items": [
{
"id": 9753601,
"data": "account1@example.com|Sample2",
"sold_at": "2026-10-11T16:58:00.000000Z"
},
{
"id": 9753602,
"data": "account1@example.com|Sample2",
"sold_at": "2026-10-11T16:58:00.000000Z"
}
]
}
}
```
**404 Not found** — Not found
```json
{
"success": false,
"error": "Order not found"
}
```
### Place an order
`POST /api/v2/orders`
**Auth:** API key
Buys a product: your balance is charged and the account lines come back in items. Manual products answer with status pending (or completed when ready stock covered it) and are delivered later. If the supplier is still delivering an order, the reply has status pending, empty (or partial) items and a deliver_by time: fetch GET /orders/{id} for the accounts (usually within 1-2 minutes). If they have not arrived by deliver_by, the order is refunded in full automatically (status refunded); do not place it again while it is pending.
| Body field | Type | Required | Description |
|---|---|---|---|
| `product_id` | integer | yes | Product id (see GET /products). |
| `quantity` | integer | yes | 1 or more; for pack products one of allowed_quantities. |
| `reward_code` | string | no | Optional discount code. |
```bash
curl -X POST "https://bulkmail.shop/api/v2/orders" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"product_id": 986, "quantity": 2}'
```
**201 Created** — Order placed *(illustrative)*
```json
{
"success": true,
"data": {
"order_id": 1232999,
"product_name": "1h - 12h edu.pl",
"quantity": 2,
"unit_price": 0.02571542,
"total_amount": 0.05143084,
"balance_remaining": 125.44856916,
"items": [
"account1@example.com:Sample2",
"account1@example.com:Sample2"
]
}
}
```
**400 Bad request** — Missing product_id
```json
{
"success": false,
"error": "product_id is required"
}
```
**400 Bad request** — Invalid pack size
```json
{
"success": false,
"error": "This product is sold in packs only. Please choose one of these quantities: 12, 25, 35, 45, 65, 85, 95, 135, 405, 540, 675, 1350.",
"errors": {
"code": "INVALID_PACK_SIZE",
"allowed_quantities": [
12,
25,
35,
45,
65,
85,
95,
135,
405,
540,
675,
1350
]
}
}
```
**400 Bad request** — Invalid reward code
```json
{
"success": false,
"error": "Invalid reward code"
}
```
**422 Validation failed or cannot be fulfilled** — More than all stock
```json
{
"success": false,
"error": "Insufficient stock available"
}
```
### Cancel an order
`POST /api/v2/orders/{id}/cancel`
**Auth:** API key
Only pending orders can be cancelled.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | integer | yes | Order id. |
```bash
curl -X POST "https://bulkmail.shop/api/v2/orders/99999999/cancel" \
-H "X-API-Key: YOUR_API_KEY"
```
**404 Not found** — Not found
```json
{
"success": false,
"error": "Order not found"
}
```
### Export delivered lines
`GET /api/v2/orders/{id}/export`
**Auth:** API key
The order's delivered lines. format=csv or format=txt returns plain lines instead of JSON.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | integer | yes | Order id. |
| `format` | query | string (json\|csv\|txt) | no | Default json. |
```bash
curl -X GET "https://bulkmail.shop/api/v2/orders/1232875/export" \
-H "X-API-Key: YOUR_API_KEY"
```
**200 OK** — JSON
```json
{
"success": true,
"data": [
{
"id": 9753601,
"data": "account1@example.com|Sample2",
"sold_at": "2026-10-11T16:58:00.000000Z"
},
{
"id": 9753602,
"data": "account1@example.com|Sample2",
"sold_at": "2026-10-11T16:58:00.000000Z"
}
]
}
```
## Wallet
Balance, transactions and deposits.
### Get your balance
`GET /api/v2/wallet/balance`
**Auth:** API key
```bash
curl -X GET "https://bulkmail.shop/api/v2/wallet/balance" \
-H "X-API-Key: YOUR_API_KEY"
```
**200 OK** — Balance
```json
{
"success": true,
"data": {
"balance": 339.60453503,
"currency": "USD"
}
}
```
### List transactions
`GET /api/v2/wallet/transactions`
**Auth:** API key
Your ledger, newest first. amount is unsigned; direction and signed_amount say whether money came in or went out.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `page` | query | integer | no | Page number, from 1. |
| `per_page` | query | integer | no | Items per page, 1-100 (default 20). |
| `type` | query | string (deposit\|withdrawal\|purchase\|refund\|custom_mail\|credit\|debit) | no | credit = admin top-up or referral reward. An unknown type returns no rows. |
| `date_from` | query | string | no | |
| `date_to` | query | string | no | |
```bash
curl -X GET "https://bulkmail.shop/api/v2/wallet/transactions?per_page=2" \
-H "X-API-Key: YOUR_API_KEY"
```
**200 OK** — Latest
```json
{
"success": true,
"data": [
{
"id": 1247991,
"type": "purchase",
"amount": 0.02394032,
"direction": "out",
"signed_amount": -0.02394032,
"balance_after": 339.60453503,
"created_at": "2026-10-11T16:58:00.000000Z"
},
{
"id": 1247879,
"type": "purchase",
"amount": 0.01197016,
"direction": "out",
"signed_amount": -0.01197016,
"balance_after": 339.62847535,
"created_at": "2026-10-11T16:30:01.000000Z"
}
],
"meta": {
"current_page": 1,
"per_page": 2,
"total": 3663,
"total_pages": 1832
}
}
```
**200 OK** — Credits only
```json
{
"success": true,
"data": [
{
"id": 1148202,
"type": "credit",
"amount": 500,
"direction": "in",
"signed_amount": 500,
"balance_after": 639.9275997,
"created_at": "2026-09-22T15:15:30.000000Z"
},
{
"id": 1141019,
"type": "credit",
"amount": 200,
"direction": "in",
"signed_amount": 200,
"balance_after": 200.02273566,
"created_at": "2026-09-21T14:59:17.000000Z"
}
],
"meta": {
"current_page": 1,
"per_page": 2,
"total": 4,
"total_pages": 2
}
}
```
### Start a deposit
`POST /api/v2/wallet/deposit`
**Auth:** API key
Creates a payment with a gateway and returns its payment_url. Gateways switched off by the shop are refused.
| Body field | Type | Required | Description |
|---|---|---|---|
| `amount` | number | yes | USD. Minimums apply per gateway. |
| `payment_method` | string (heleket\|crypto\|cryptomus\|piprapay) | yes | Alias: gateway. |
| `crypto_currency` | string | no | Default USDT. |
| `crypto_network` | string | no | Default TRON. |
```bash
curl -X POST "https://bulkmail.shop/api/v2/wallet/deposit" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"amount": 10, "payment_method": "heleket"}'
```
**200 OK** — Deposit created *(illustrative)*
```json
{
"success": true,
"data": {
"deposit_id": 52011,
"amount": 10,
"payment_method": "crypto",
"status": "pending",
"payment_url": "https://pay.heleket.com/pay/00000000-0000-0000-0000-000000000000",
"expires_at": "2026-10-11T18:30:00.000000Z"
}
}
```
**422 Validation failed or cannot be fulfilled** — Invalid
```json
{
"success": false,
"error": "Validation failed",
"errors": {
"amount": [
"Minimum deposit amount is $0.25"
],
"payment_method": [
"Valid payment method is required (heleket, crypto, cryptomus, piprapay)"
]
}
}
```
### List deposits
`GET /api/v2/wallet/deposits`
**Auth:** API key
Payment-gateway deposits only. Admin top-ups appear as credit transactions instead.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `page` | query | integer | no | Page number, from 1. |
| `per_page` | query | integer | no | Items per page, 1-100 (default 20). |
| `status` | query | string (pending\|completed\|approved\|rejected\|cancelled) | no | |
```bash
curl -X GET "https://bulkmail.shop/api/v2/wallet/deposits" \
-H "X-API-Key: YOUR_API_KEY"
```
**200 OK** — Deposits
```json
{
"success": true,
"data": [],
"meta": {
"current_page": 1,
"per_page": 20,
"total": 0,
"total_pages": 0
}
}
```
**200 OK** — With a deposit *(illustrative)*
```json
{
"success": true,
"data": [
{
"id": 52011,
"amount": 10,
"status": "completed",
"payment_method": "crypto",
"created_at": "2026-10-11T16:30:00.000000Z",
"updated_at": "2026-10-11T16:41:12.000000Z"
}
],
"meta": {
"current_page": 1,
"per_page": 20,
"total": 1,
"total_pages": 1
}
}
```
### Get a deposit
`GET /api/v2/wallet/deposits/{id}`
**Auth:** API key
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | integer | yes | Deposit id. |
```bash
curl -X GET "https://bulkmail.shop/api/v2/wallet/deposits/52011" \
-H "X-API-Key: YOUR_API_KEY"
```
**200 OK** — Deposit *(illustrative)*
```json
{
"success": true,
"data": {
"id": 52011,
"status": "completed",
"amount": 10,
"payment_method": "crypto"
}
}
```
**404 Not found** — Not found
```json
{
"success": false,
"error": "Deposit not found"
}
```
## Purchases
Every account line delivered to you.
### List purchased lines
`GET /api/v2/purchases`
**Auth:** API key
Every account line delivered to you, newest first.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `page` | query | integer | no | Page number, from 1. |
| `per_page` | query | integer | no | Items per page, 1-100 (default 20). |
| `product_id` | query | integer | no | |
| `order_id` | query | integer | no | |
```bash
curl -X GET "https://bulkmail.shop/api/v2/purchases?per_page=2" \
-H "X-API-Key: YOUR_API_KEY"
```
**200 OK** — Latest
```json
{
"success": true,
"data": [
{
"id": 9753601,
"product_id": 13,
"product_name": "Gmail Edu domain rental for 24 hours (.us domain) with Gmail",
"order_id": 1232875,
"data": "account1@example.com|Sample2",
"sold_at": "2026-10-11T16:58:00.000000Z"
},
{
"id": 9753602,
"product_id": 13,
"product_name": "Gmail Edu domain rental for 24 hours (.us domain) with Gmail",
"order_id": 1232875,
"data": "account1@example.com|Sample2",
"sold_at": "2026-10-11T16:58:00.000000Z"
}
],
"meta": {
"current_page": 1,
"per_page": 2,
"total": 14574,
"total_pages": 7287
}
}
```
### Get a purchased line
`GET /api/v2/purchases/{id}`
**Auth:** API key
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | integer | yes | Purchase (line) id. |
```bash
curl -X GET "https://bulkmail.shop/api/v2/purchases/9753601" \
-H "X-API-Key: YOUR_API_KEY"
```
**200 OK** — Line
```json
{
"success": true,
"data": {
"id": 9753601,
"product_id": 13,
"product_name": "Gmail Edu domain rental for 24 hours (.us domain) with Gmail",
"order_id": 1232875,
"data": "account1@example.com|Sample2",
"sold_at": "2026-10-11T16:58:00.000000Z"
}
}
```
**404 Not found** — Not found
```json
{
"success": false,
"error": "Purchase not found"
}
```
## API Keys
Manage the keys that authenticate you.
### List your API keys
`GET /api/v2/api-keys`
**Auth:** API key
Active keys, prefix only. last_used_at updates at most every 5 minutes.
```bash
curl -X GET "https://bulkmail.shop/api/v2/api-keys" \
-H "X-API-Key: YOUR_API_KEY"
```
**200 OK** — Keys
```json
{
"success": true,
"data": [
{
"id": 436,
"key_prefix": "sk_live_a1b2...",
"created_at": "2026-07-20T09:25:29.000000Z",
"last_used_at": "2026-10-11T17:20:46.000000Z"
},
{
"id": 737,
"key_prefix": "sk_live_a1b2...",
"created_at": "2026-10-11T14:42:24.000000Z",
"last_used_at": "2026-10-11T17:33:00.000000Z"
}
]
}
```
### Create an API key
`POST /api/v2/api-keys`
**Auth:** API key
Up to 5 active keys. The full key is shown only in this response.
```bash
curl -X POST "https://bulkmail.shop/api/v2/api-keys" \
-H "X-API-Key: YOUR_API_KEY"
```
**201 Created** — Created *(illustrative)*
```json
{
"success": true,
"message": "API key created. Store it securely - it won't be shown again.",
"data": {
"id": 812,
"key": "sk_live_0000000000000000000000000000000000000000000000000000000000000000",
"created_at": "2026-10-11T17:00:00.000000Z"
}
}
```
**400 Bad request** — Limit reached *(illustrative)*
```json
{
"success": false,
"error": "Maximum of 5 active API keys allowed"
}
```
### Revoke an API key
`DELETE /api/v2/api-keys/{id}`
**Auth:** API key
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | integer | yes | API key id. |
```bash
curl -X DELETE "https://bulkmail.shop/api/v2/api-keys/812" \
-H "X-API-Key: YOUR_API_KEY"
```
**200 OK** — Revoked *(illustrative)*
```json
{
"success": true,
"message": "API key revoked successfully"
}
```
**404 Not found** — Not found
```json
{
"success": false,
"error": "API key not found"
}
```
## Unknown paths
Any method on a path that does not exist:
```json
{
"success": false,
"error": "No endpoint for GET /api/v2/nope"
}
```