Social & Communication
Receive codes from social and messaging apps.
1 number · 1 website · 1 SMS
Receive SMS online without sharing your personal phone number.
For business, sign-ups and everyday privacy.
Pick a country and the website you want a code from. CodeySMS works on every device and delivers your SMS 24/7.
Any website works. Can't find yours? Just type it above.
CodeySMS numbers work for sign-ups on thousands of websites and apps, from web shops to games.
Lightning-fast delivery with no hidden fees – you only pay when the SMS is successfully delivered
Use the temporary number with the correct country code.
Your SMS arrives instantly. You only pay on delivery.
Our numbers receive SMS from a wide range of online services
Receive codes from social and messaging apps.
Use a number for marketplaces, delivery apps, tickets and lifestyle services.
Receive codes from gaming and entertainment services.
Excellent
Pay safely with crypto. Payments go through a trusted crypto payment provider, and the amount is added to your balance automatically once the payment is confirmed.
Pay with crypto for more privacy.
Don't see your coin? Contact us and we'll look into adding it.
Easily add money to your account with the cryptocurrency of your choice.
Your balance is automatically deducted with each SMS verification and refunded if no SMS arrives, so you only pay for what you use.
My numbers gives you a clear overview of every number, code and price, so you always know where your money is going.
Easily build SMS reception into your own tools and workflows with our API. Create your personal API key and automate ordering numbers and reading codes.
Explore API documentationTop up your balance once and use it whenever you like. Your balance never expires.
€0.50per SMS
Pay with crypto such as Bitcoin, Ethereum, USDT and Litecoin. The amount is added to your balance as soon as the payment is confirmed on the blockchain.
We currently offer Netherlands (+31), Belgium (+32) and Germany (+49) numbers. More countries may be added later.
Yes, if you already received an SMS on it. You can re-use the same number for the same website, for example when you need a new code: open My numbers and click Re-use. A re-use costs half the price and works as long as the number is still active with us. No one else will ever get that number for that website.
Each number is only used once for a given website. When every number we have in that country has already been used for that website, you see this message. Choose another country, or contact our support and we will add more numbers for it.
Unfortunately the SMS didn't arrive in time. But you don't lose anything: the amount is returned to your balance automatically. Just make a new order and try again.
Until the first SMS arrives or the time runs out. After that the number is never given to anyone else for the same website, but you can re-use it yourself.
Cancel the request or let the time run out. The amount is returned to your balance automatically.
Each order is for one SMS. Need a new code? Re-use your number from My numbers, or make a new order.
It depends on the coin. USDT (TRC20) and Litecoin usually confirm within a few minutes; Bitcoin can take longer.
Only you. When you use one of our numbers on a website, only you receive that website's SMS, just once. The number is never given to anyone else for that same website.
No. Use CodeySMS in line with the terms of the website you're receiving the code for. Misuse, such as fraud or mass account creation, gets your account blocked.
Alleen zichtbaar voor jou als eigenaar.
Geen toegang. Log in met een beheerdersaccount.
| Land | Soort | Actief | Vrij |
|---|
| Saldo | Bestellingen | Huur | Laatste bestelling | Sinds |
|---|
| Wanneer | Bedrag | Soort | Kenmerk |
|---|
| # | Website | Nummer | Status | Prijs | Wanneer |
|---|
| # | Nummer | Periode | Status | Tot | Auto |
|---|
| # | Klant | Website | Nummer | Status | Prijs | Wanneer |
|---|
| Wanneer | Klant | Bedrag | Op saldo | Status | Bijgeschreven | Kenmerk |
|---|
| Nummer | Land | Soort | Status | Websites gebruikt | Huurder | Bron |
|---|
API v1
A JSON API to order numbers and read verification codes from your own software.
Base URLhttps://www.codeysms.com/api/v1
Every path below is relative to the base URL. Every response is JSON. Amounts are always in EUR, timestamps always in UTC (ISO 8601).
The API offers the same two products as the website. A one-time number receives one SMS for one website and stays open for 20 minutes; if no SMS arrives, or you cancel, the price goes back to your balance. A rental number is yours for 1, 3, 6 or 12 months and receives every SMS sent to it.
/api/v1/openapi.json. That file describes every endpoint, field and error code, so it can write a working client without guessing.Log in to create an API key. A key gives full access to your account through the API, including your balance, so keep it secret.
Your new key. Copy it now: for your security we only show it once.
| Name | Key | Created | Last used |
|---|
You can have up to 5 active keys. Revoking a key stops it working immediately.
Send your key in the Authorization header of every request. Keys are never accepted in the URL, because URLs end up in logs and browser history.
curl https://www.codeysms.com/api/v1/account \
-H "Authorization: Bearer $CODEYSMS_KEY"
GET /account is the cheapest way to check that a key works. A missing key answers 401 unauthenticated, a wrong or revoked key 401 invalid_token.
POST /orders.GET /orders/{id}/messages every few seconds until data is not empty.export CODEYSMS_KEY="csk_your_key"
# 1. Order a number for a website
curl -s -X POST https://www.codeysms.com/api/v1/orders \
-H "Authorization: Bearer $CODEYSMS_KEY" \
-H "Content-Type: application/json" \
-d '{"website": "myshop.com", "country": "NL", "max_price": "0.50"}'
# 2. Poll every few seconds until data is not empty
curl -s https://www.codeysms.com/api/v1/orders/123/messages \
-H "Authorization: Bearer $CODEYSMS_KEY"
# No SMS after all? Cancel and get your money back
curl -s -X POST https://www.codeysms.com/api/v1/orders/123/cancel \
-H "Authorization: Bearer $CODEYSMS_KEY"const KEY = process.env.CODEYSMS_KEY;
const api = (path, body) =>
fetch("https://www.codeysms.com/api/v1" + path, {
method: body ? "POST" : "GET",
headers: { Authorization: `Bearer ${KEY}`, "Content-Type": "application/json" },
body: body ? JSON.stringify(body) : undefined,
}).then(async (r) => {
const json = await r.json();
if (!r.ok) throw new Error(json.code + ": " + json.detail);
return json;
});
const order = await api("/orders", { website: "myshop.com", country: "NL" });
console.log("Use this number:", order.phone_number);
let code = null;
while (!code) {
await new Promise((r) => setTimeout(r, 3000));
const { data, order_status } = await api(`/orders/${order.id}/messages`);
if (data.length) code = data[0].code;
else if (order_status !== "pending") throw new Error("Order " + order_status);
}
console.log("Code:", code);import os, time, requests
KEY = os.environ["CODEYSMS_KEY"]
H = {"Authorization": f"Bearer {KEY}"}
BASE = "https://www.codeysms.com/api/v1"
order = requests.post(f"{BASE}/orders", headers=H,
json={"website": "myshop.com", "country": "NL"}).json()
print("Use this number:", order["phone_number"])
while True:
time.sleep(3)
r = requests.get(f"{BASE}/orders/{order['id']}/messages", headers=H).json()
if r["data"]:
print("Code:", r["data"][0]["code"])
break
if r["order_status"] != "pending":
raise SystemExit("Order " + r["order_status"])POST /orders answers 201 Created with the order:
HTTP/1.1 201 Created
Location: /api/v1/orders/123
{
"object": "order",
"id": 123,
"status": "pending",
"website": "myshop.com",
"country": "NL",
"phone_number": "+31612345678",
"phone_number_local": "0612345678",
"price": { "amount": "0.50", "amount_minor": 50, "currency": "EUR" },
"reusable": false,
"created_at": "2026-11-01T12:00:00Z",
"expires_at": "2026-11-01T12:20:00Z",
"closed_at": null,
"code": null,
"messages": []
}
Once the SMS arrives, GET /orders/{id}/messages returns it:
{
"data": [
{
"object": "message",
"sender": "MyShop",
"text": "Your verification code is 591204.",
"code": "591204",
"received_at": "2026-11-01T12:01:12Z"
}
],
"order_id": 123,
"order_status": "completed"
}
code is the verification code we found in the message, so you don't need your own regex. If there is no clear code, it is null and text has the full message.data with order_status: "pending" means: keep waiting. Any other status means the order is over.phone_number is in international format (E.164); phone_number_local is the national format, for forms that want that.409 concurrent_order_limit.Every error is an application/problem+json document (RFC 9457) with the matching HTTP status. Branch on code: these values never change meaning. retryable tells you whether the same request can succeed later.
HTTP/1.1 402 Payment Required
Content-Type: application/problem+json
{
"type": "https://www.codeysms.com/api#error-insufficient_balance",
"title": "Insufficient balance",
"status": 402,
"code": "insufficient_balance",
"detail": "Your balance is too low. Please top up first.",
"retryable": false
}
| code | HTTP | Retryable | Meaning |
|---|---|---|---|
unauthenticated | 401 | no | No API key was sent. |
invalid_token | 401 | no | The API key is not valid or was revoked. |
account_restricted | 403 | no | This account cannot place orders. Contact support. |
insufficient_balance | 402 | no | Your balance does not cover this. Top up first. |
not_found | 404 | no | No such endpoint. |
order_not_found | 404 | no | No order with that id on your account. |
rental_not_found | 404 | no | No rental with that id on your account. |
method_not_allowed | 405 | no | Wrong HTTP method. The Allow header lists the right ones. |
out_of_stock | 409 | yes | No number is available for that website and country right now. Try again later or another country. |
concurrent_order_limit | 409 | no | You already have an open order. Finish or cancel it first. |
order_not_open | 409 | no | The order is already completed, cancelled or expired. |
number_unavailable | 409 | no | The number behind this order is no longer available for re-use. |
number_busy | 409 | yes | The number is busy with another order right now. Try again in a few minutes. |
unsupported_media_type | 415 | no | Send JSON with Content-Type: application/json. |
validation_failed | 422 | no | The request is not valid. errors names the fields. |
invalid_website | 422 | no | The website is not a valid domain, such as myshop.com. |
website_blocked | 422 | no | We don't issue numbers for banks and government services. |
country_not_supported | 422 | no | We don't offer that country. |
invalid_plan | 422 | no | Unknown rental plan. Valid plans are listed in the response. |
order_not_completed | 422 | no | Only an order that received an SMS can be re-used. |
price_above_maximum | 422 | no | The price is above your max_price. Nothing was bought. |
rate_limited | 429 | yes | Too many requests. Wait for the Retry-After header. |
hourly_order_limit | 429 | yes | You reached the maximum number of orders per hour. |
internal_error | 500 | yes | Something went wrong on our side. Try again shortly. |
Limits count per account, per minute. Reading is generous, because polling for a code is cheap; ordering is stricter.
| Bucket | Per minute | Applies to |
|---|---|---|
read | 240 | All authenticated GET requests, including polling |
write | 60 | Cancelling orders and changing rentals |
order | 30 | Ordering, re-using and renting |
public | 60 | Endpoints without a key, counted per IP address |
Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (Unix time). Over the limit you get 429 rate_limited with a Retry-After header in seconds.
GET /orders uses a cursor: pass limit (default 25, maximum 100) and keep sending pagination.next_cursor back as cursor until has_more is false. Treat the cursor as an opaque string.
| Method | Path | What it does | Limit |
|---|---|---|---|
| GET | /account | Your e-mail address, balance and number of open orders. | read |
| GET | /countries | Countries and whether a number is available. No key needed. | public |
| GET | /prices | Current prices for one-time numbers, re-use and rental plans. No key needed. | public |
| POST | /orders | Order a one-time number. Body: website, country (NL, BE or DE), optional max_price. Answers 201. | order |
| GET | /orders | Your orders, newest first. Query: limit (1–100), cursor, status. | read |
| GET | /orders/{id} | One order, including its messages. | read |
| GET | /orders/{id}/messages | The messages of one order. Poll this until data is not empty. | read |
| POST | /orders/{id}/cancel | Cancel an open order. The price goes back to your balance. | write |
| POST | /orders/{id}/reuse | Order the same number again for the same website, at half price. Only after the order received an SMS. Answers 201. | order |
| GET | /rentals | Your rental numbers. | read |
| POST | /rentals | Rent a number. Body: plan (m1, m3, m6, m12), country, optional auto_renew (default true). Answers 201. | order |
| GET | /rentals/{id} | One rental. | read |
| GET | /rentals/{id}/messages | Messages received on a rental, newest first (last 100). | read |
| POST | /rentals/{id}/auto-renew | Turn auto-renewal on or off. Body: enabled (true or false). | write |
| GET | /openapi.json | The full machine-readable description of this API (OpenAPI 3.1). | public |
pending waiting for the SMS · completed SMS received · cancelled cancelled, money back · expired time ran out without an SMS, money back.
Amounts are objects: {"amount": "0.50", "amount_minor": 50, "currency": "EUR"}. Use amount_minor (cents) for calculations.
id, status (active or ended), country, phone_number, phone_number_local, plan, months, price, auto_renew, started_at, ends_at, ended_at.
We're here to help!
You can e-mail us with any question or problem. We'll get back to you as soon as possible.
support@codeysms.comTip: when you contact us, mention the e-mail address of your account and, for a question about an order, the order number (for example #123). Then we can help you faster.
Long-term solution
Rent a dedicated number just for you and receive every SMS at no extra cost.
Starting from€5.83/mo
Save more with a longer period
Every SMS sent to your number appears here automatically.
A private number with everything you need for long-term use.
The number is assigned to you alone. No one else can see your messages.
Get every SMS sent to your number, from any website or app.
Pay once per period. No cost per message and no hidden fees.
Keep your number as long as you like with automatic renewal from your balance.
Pick a period and a number from the Netherlands (+31), Belgium (+32) or Germany (+49).
Pay from your balance. Your number is assigned to your account straight away.
All incoming messages appear on this page in real time.
For the period you choose: 1, 3, 6 or 12 months. With auto-renewal on, your rental renews from your balance at the end of each period.
A rental can't be refunded once the number is assigned, because the number is then reserved for you alone. Not sure if a website accepts our numbers? Try it first with a one-time number.
With auto-renewal on and enough balance, it renews automatically. Otherwise the number is switched off and never given to anyone else, so no one can receive your messages.
As many as you like. There is no cost per message.
You can receive their SMS codes on it. Voice calls are not supported, so verification by phone call won't work.
Start receiving SMS on your own number today. No sharing, no limits.