# 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.

Important Notice

", "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.

Important Notice

", "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" } ```