XMailHub.net
// API

Email account API

Last updated: July 15, 2026

Yes, there is an API to buy email accounts programmatically. One endpoint needs no API key at all: GET https://api.xmailhub.net/stock returns live prices and stock for every product as JSON, to anyone, right now. Everything else, your balance, purchasing and mail reading, takes a key and spends a prepaid balance.

The whole surface is five GET endpoints on https://api.xmailhub.net. You can verify the catalogue before you register: open the stock URL in a browser and you get back status, code and a data array of products, each with an Account code, a Name, a Price as a string and a Stock count. Fresh Hotmail and Outlook are $0.004, trusted (aged) Hotmail and Outlook are $0.040, Gmail is $0.350. Orders run from 1 to 100,000 accounts and the unit price is identical at every quantity. Funding is cryptocurrency only, through Plisio, using USDT TRC20, Litecoin or Tron. There is no per-order checkout to automate around: you top the balance up once and the API draws it down.

All five endpoints, base URL https://api.xmailhub.net
EndpointKeyReturns
GET /stockNostatus, code, data[] with Name, Price (string) and Stock (integer) per product.
GET /balance/KEYYescode, balance (string), date as dd/mm/yyyy HH:MM:SS.
GET /purchase/KEY/CODE/QUANTITYYesstatus, code, message, purchase_id, balance, price, data[] with Email, Password, AccessToken, RefreshToken, ClientId.
GET /mailinfo/KEY?mail=ADDRESSYescode, data with mail, password, accessToken, refreshToken, clientId.
GET /mailreader/KEY?mail=ADDRESSYescode, message, data with email_address and the inbox messages. Add &html for raw HTML.
Product codes for the CODE segment of /purchase. Also readable live from the Account field of /stock.
CodeProductPrice
HotmailHotmail Fresh$0.004
OutlookOutlook Fresh$0.004
Hotmail_TrustedHotmail Trusted$0.040
Outlook_TrustedOutlook Trusted$0.040
Live prices and stock, the same numbers /stock returns
ProductPriceStock
Hotmail Fresh$0.004Out
Outlook Fresh$0.004In stock
Hotmail Trusted$0.020Out
Outlook Trusted$0.0201
Gmail$0.350Out

The stock endpoint is public and needs no key

GET https://api.xmailhub.net/stock takes no key, no header and no account. That is deliberate, and it is the endpoint to start with. The response looks like this: {"status":"success","code":200,"data":[{"Name":"Hotmail Fresh","Price":"0.004","Stock":34},{"Name":"Outlook Trusted","Price":"0.040","Stock":17}]}. Price is a string, not a number, so parse it rather than assuming a float, and Stock is an integer that moves constantly as other buyers take accounts. Two honest notes. First, the data array lists product names, not the product codes you pass to the purchase endpoint, so the mapping table above is where those codes live. Second, the count is read live at request time rather than from a long cache, which is why a product can read 34 on one call and 0 on the next. Poll it right before you buy, not once at the start of a long job.

Getting an API key and funding a balance

Your API key is in your account dashboard, on the API page, and it is generated for you when you register. There is no application form and no approval step. You can rotate it from the same page whenever you want, which is worth doing if a key has been sitting in an old script or a shared config for a while, since rotation costs you one deploy and a leaked key costs you your balance. The key authenticates in three interchangeable ways: as a path segment, as ?apiKey= in the query string, or as an X-API-Key header. All three hit the same handler. Money works the same way for the API as for the store. You fund a prepaid balance with cryptocurrency through Plisio, which takes USDT on TRC20, Litecoin and Tron, and every purchase call debits that balance. Read the current figure with GET /balance/YOUR_KEY, which returns code, balance as a string, and date formatted as dd/mm/yyyy HH:MM:SS.

Buying accounts: /purchase/KEY/CODE/QUANTITY

A purchase is one request: GET https://api.xmailhub.net/purchase/YOUR_KEY/Hotmail/10 buys ten fresh Hotmail accounts. CODE is the product's API code, and there are four live ones: Hotmail, Outlook, Hotmail_Trusted and Outlook_Trusted. Matching is case-insensitive, so hotmail_trusted works. The Account field in the /stock response gives you the code for every product, so you do not have to hard-code this list. Quantity runs from 1 to 100,000 per order, and the unit price never changes with volume, so ten thousand fresh Hotmail costs ten thousand times $0.004. Yes, a mutating call over GET is unusual, and no, we are not going to pretend otherwise. It exists because the old system's URLs looked exactly like this and thousands of working scripts point at them; changing the verb would have broken every one of them to satisfy a convention. Treat the consequences seriously: this URL spends real money, so keep it out of anything that retries blindly, prefetches links, or writes full URLs to a shared log.

What the purchase response returns

A successful purchase returns status, code, message, purchase_id, balance, price and a data array with one object per account. Each object has Email, Password, AccessToken, RefreshToken and ClientId. Those last three are the OAuth2 fields that let you reach the mailbox over IMAP or Microsoft Graph without touching the interactive web login, which is where Microsoft tends to ask for a phone number. AccessToken comes back as "-" when an account has no token stored, so check for that before feeding it to a mail library. balance is your remaining balance after the debit and price is the unit price you actually paid, both as strings. purchase_id is the order reference, and it is the one field worth writing down: it identifies the order to support if an account will not log in. The credentials also stay in your order history, so a script that dies after the response has been sent has not lost the accounts.

Reading a mailbox: /mailreader and /mailinfo

Two endpoints work on accounts you already own. GET /mailreader/[email protected] reads the inbox and returns code, message and a data object holding email_address plus the messages the upstream reader found, each carrying the date, sender_email, sender_name, subject, message, folder and id. Append &html to get raw HTML bodies instead of cleaned text. GET /mailinfo/[email protected] returns the stored credentials for one account: mail, password, accessToken, refreshToken and clientId. Both check ownership against your order history, so an address you did not buy returns 400 with the key publicapi.invalid_mail rather than leaking anything. Both also require the mail parameter; without it you get 400 and the key publicapi.missing_params. Reading depends on an upstream mail service, so if that service is unreachable the call returns 503 rather than an empty inbox. Treat 503 as retry later, not as no mail.

Errors, status codes and the quirks worth knowing

Error bodies carry success: false, a machine-readable code, and both messageKey and messageText, the latter translated by your Accept-Language header or ?lang=. A missing key returns 401 with code API_KEY_MISSING, an invalid one returns 401 with API_KEY_INVALID, and a key belonging to a suspended account returns 403 with ACCOUNT_INACTIVE. Do not lump those together: 401 means fix your key, 403 means talk to support, and neither is worth retrying. An unknown product code returns 404. Asking for more than the supplier has returns 400 with INSUFFICIENT_STOCK, and the message tells you how many are actually available, so a script can lower the quantity and try again. A quantity outside 1 to 100,000 returns 400 QUANTITY_OUT_OF_RANGE, an empty balance returns 400 INSUFFICIENT_BALANCE. Two genuine oddities: calling /purchase with the query format and no code or quantity returns HTTP 400 with a body that says code: 403, and during maintenance every endpoint returns 503 with code: 999.

Two URL formats, and old scripts

Every endpoint answers on two shapes at once. The legacy path format puts the key in the URL: /balance/KEY, /purchase/KEY/CODE/QUANTITY, /mailinfo/KEY?mail=..., /mailreader/KEY?mail=.... The query format keeps the path clean: /balance?apiKey=KEY, /purchase?apiKey=KEY&code=Hotmail&quantity=10. Both reach the same handler and return the same body, and a third option, the X-API-Key header, works on either. This is not a deprecation with a countdown attached. Both formats are live side by side with no cutover date, which is why a script written years ago against the old PHP subdomain keeps running: point it at https://api.xmailhub.net, keep the key, done. If you are writing something new, prefer the header. Keys in URLs end up in access logs, browser history, proxy caches and the referrer of any page you fetch afterwards, and none of those are places you want a key that spends money.

Frequently asked questions

Do I need an API key to check stock?

+

No. GET https://api.xmailhub.net/stock is public. No key, no header, no account, no registration. Open it in a browser and you get JSON back: a status field, a code field, and a data array with one entry per product carrying Name, Price and Stock. That is the fastest way to confirm what is actually for sale and at what price before you commit to anything, and it is the endpoint to poll in a loop, since it costs you nothing. Every other endpoint, balance, purchase, mailinfo and mailreader, needs your key. Note that the stock response gives product names rather than the codes the purchase endpoint expects, so use the mapping table on this page to translate between the two.

How do I get an API key?

+

Register an account and it is already there, on the API page of your dashboard. No application, no approval, no waiting. That page also shows the base URL and a worked example for each endpoint with your real key filled in, so you can copy a curl command straight out of it. You can rotate the key from the same page at any time, and rotation takes effect immediately, so anything still using the old key starts getting 401 with code API_KEY_INVALID. The key can travel three ways: a path segment, ?apiKey= in the query string, or an X-API-Key header. Prefer the header for new code, because keys in URLs leak into logs and history.

What happens if stock runs out mid-order?

+

The order fails as a whole and you are not charged. Purchases are atomic: the accounts are sourced first, and if the full quantity cannot be delivered, nothing is written and the balance is never debited, so you never end up half-billed for a partial batch. You get HTTP 400 with code INSUFFICIENT_STOCK, and the message states how many are genuinely available against how many you asked for, which is enough for a script to retry at the lower number automatically. If the product is completely out, the code is OUT_OF_STOCK instead. Both are worth handling separately from a 401. Stock generally refills, so backing off and polling /stock is the right response rather than failing the job.

Is there a sandbox or a test mode?

+

No, and there is no fake key that returns fake accounts. There is something better for the read path: /stock is public, so you can build and test everything that reads the catalogue before you have registered or spent a cent. For the write path, the price is the sandbox. A single fresh Hotmail account costs $0.004, so buying one real account is the cheapest integration test you will ever write, and it exercises the exact code path production will hit rather than a mock of it. Do that first, with quantity 1, and check the response parses before you point a loop at it. Purchases cannot be reversed, so a real test at $0.004 beats discovering a bug at quantity 10,000.

Why is purchase a GET request instead of a POST?

+

Compatibility, honestly. The old PHP system exposed purchase as GET /purchase/KEY/CODE/QUANTITY and a lot of working scripts still call exactly that URL. Moving to POST would have broken all of them for the sake of a convention, so the shape stayed. It is not REST-pure and we are not going to describe it as though it were. What matters is that you handle it accordingly, because a URL that spends money is not safe to treat like a normal GET. Keep it out of anything that retries automatically on timeout, out of link prefetchers and crawlers, and out of logs that record full URLs, since the key is in the path. Use the header format and a query string if that worries you.

Which product codes can I pass to the purchase endpoint?

+

Four are live: Hotmail for Hotmail Fresh at $0.004, Outlook for Outlook Fresh at $0.004, Hotmail_Trusted for Hotmail Trusted at $0.040, and Outlook_Trusted for Outlook Trusted at $0.040. Matching is case-insensitive. Gmail is the exception: it is stocked from inventory rather than a supplier and carries no short code, so the literal string Gmail returns 404 with the key publicapi.product_not_found. What /stock hands back for Gmail is its long public id, and that id does work in the CODE segment. At the moment it gets you SALE_CLOSED rather than accounts, because Gmail is temporarily off sale. You do not need to hard-code any of this: every product's code is in the Account field of the /stock response, which is the discovery mechanism, and the table here is a convenience rather than the source of truth. If a code returns 404 that used to work, the product has been taken off sale rather than renamed.

How do I read the inbox of an account I bought over the API?

+

GET /mailreader/[email protected] returns the inbox as JSON: each message carries date, sender_email, sender_name, subject, message, folder and id, which is everything you need to pull a verification code out with a regex. Add &html for raw HTML bodies rather than cleaned text. You can only read addresses from your own orders; anything else returns 400. If you would rather talk to Microsoft directly, GET /mailinfo/[email protected] hands back the account's password, accessToken, refreshToken and clientId, and those work with IMAP or Microsoft Graph from your own code. The reader depends on an upstream service, so a 503 means try again shortly rather than the mailbox being empty.

Related pages

Ready to build against it?

Check https://api.xmailhub.net/stock right now, no key needed. Register when you want to buy.

Open the store →