API-Dokumentation
Programmatischer Zugriff auf virtuelle Nummern, Bestellungen und Kontoguthaben.
⟩ Authentifizierung
Alle API-Anfragen erfordern einen Bearer-Token. Generieren Sie einen in den Kontoeinstellungen im Dashboard und fügen Sie ihn jeder Anfrage hinzu:
Anfragen ohne gültigen Token erhalten eine 401 UNAUTHORIZED-Antwort.
⟩ Basis-URL
Alle nachfolgenden Endpunkt-Pfade sind relativ zu:
⟩ Antwortformat
Jede Antwort gibt JSON mit einer konsistenten Umschlagsstruktur zurück. Alle Antworten enthalten einen x-request-id-Header für Debugging.
{
"success": true,
"data": { ... }
} {
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable message"
}
} /catalog/countries Gibt eine Liste aller verfügbaren Länder zurück.
Parameter
Keine
Beispielanfrage
curl -s https://api.smscode.gg/v1/catalog/countries \
-H "Authorization: Bearer YOUR_API_TOKEN" const res = await fetch("https://api.smscode.gg/v1/catalog/countries", {
headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json(); import requests
res = requests.get("https://api.smscode.gg/v1/catalog/countries",
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Beispielantwort
{
"success": true,
"data": [
{
"id": 6,
"code": "ID",
"name": "Indonesia",
"dial_code": "+62",
"emoji": "🇮🇩",
"active": true
}
]
} /catalog/services Gibt eine Liste der verfügbaren Dienste (Plattformen) zurück. Optional nach Land filterbar.
Query-Parameter
| Name | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
country_id | integer | Nein | Dienste für dieses Land filtern |
Beispielanfrage
curl -s "https://api.smscode.gg/v1/catalog/services?country_id=6" \
-H "Authorization: Bearer YOUR_API_TOKEN" const res = await fetch("https://api.smscode.gg/v1/catalog/services?country_id=6", {
headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json(); import requests
res = requests.get("https://api.smscode.gg/v1/catalog/services",
params={"country_id": 6},
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Beispielantwort
{
"success": true,
"data": [
{
"id": 3,
"code": "wa",
"name": "WhatsApp",
"active": true
}
]
} /catalog/products Gibt eine paginierte Liste der verfügbaren Produkte zurück. Filter nach Land und/oder Plattform möglich.
Query-Parameter
| Name | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
country_id | integer | Nein | Nach Länder-ID filtern |
platform_id | integer | Nein | Nach Plattform-/Dienst-ID filtern |
sort | string | Nein | Sortierung: price_asc (Standard), price_desc, available_asc, available_desc, name_asc, name_desc |
limit | integer | Nein | Ergebnisse pro Seite (1–10.000, Standard 1.000) |
page | integer | Nein | Seitennummer (min. 1, Standard 1) |
Beispielanfrage
curl -s "https://api.smscode.gg/v1/catalog/products?country_id=6&platform_id=3&limit=10&page=1" \
-H "Authorization: Bearer YOUR_API_TOKEN" const params = new URLSearchParams({
country_id: "6", platform_id: "3", limit: "10", page: "1",
});
const res = await fetch(`https://api.smscode.gg/v1/catalog/products?${params}`, {
headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json(); import requests
res = requests.get("https://api.smscode.gg/v1/catalog/products",
params={"country_id": 6, "platform_id": 3, "limit": 10, "page": 1},
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Beispielantwort
{
"success": true,
"data": [
{
"id": 142,
"name": "WhatsApp Indonesia",
"country_id": 6,
"platform_id": 3,
"available": 42,
"price": 15000,
"active": true
}
],
"meta": { "page": 1, "limit": 10, "count": 1 }
} /catalog/exchange-rate Gibt den aktuellen Wechselkurs für ein Währungspaar zurück. Nützlich zur Preisumrechnung.
Query-Parameter
| Name | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
pair | string | Nein | Währungspaar (Standard: USD/IDR) |
Beispielanfrage
curl -s "https://api.smscode.gg/v1/catalog/exchange-rate?pair=USD/IDR" \
-H "Authorization: Bearer YOUR_API_TOKEN" const res = await fetch("https://api.smscode.gg/v1/catalog/exchange-rate?pair=USD/IDR", {
headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json(); import requests
res = requests.get("https://api.smscode.gg/v1/catalog/exchange-rate",
params={"pair": "USD/IDR"},
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Beispielantwort
{
"success": true,
"data": {
"pair": "USD/IDR",
"base_currency": "USD",
"quote_currency": "IDR",
"rate": 16250
}
} /balance Gibt das Kontoguthaben des authentifizierten Nutzers in IDR zurück.
Parameter
Keine
Beispielanfrage
curl -s https://api.smscode.gg/v1/balance \
-H "Authorization: Bearer YOUR_API_TOKEN" const res = await fetch("https://api.smscode.gg/v1/balance", {
headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json(); import requests
res = requests.get("https://api.smscode.gg/v1/balance",
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Beispielantwort
{
"success": true,
"data": {
"currency": "IDR",
"balance": 500000
}
} /orders Gibt eine Liste der Bestellungen des authentifizierten Nutzers zurück, sortiert nach Aktualität. Unterstützt Filterung nach Status und Paginierung per Offset.
Query-Parameter
| Name | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
limit | integer | Nein | Max. Ergebnisse (1–100, Standard 20) |
offset | integer | Nein | Anzahl der zu überspringenden Ergebnisse (Standard 0) |
status | string | Nein | Nach Status filtern: ACTIVE, OTP_RECEIVED, COMPLETED, CANCELED, EXPIRED (Groß-/Kleinschreibung egal) |
Beispielanfrage
curl -s "https://api.smscode.gg/v1/orders?limit=5&status=ACTIVE" \
-H "Authorization: Bearer YOUR_API_TOKEN" const params = new URLSearchParams({
limit: "5", status: "ACTIVE", offset: "0",
});
const res = await fetch(`https://api.smscode.gg/v1/orders?${params}`, {
headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json(); import requests
res = requests.get("https://api.smscode.gg/v1/orders",
params={"limit": 5, "status": "ACTIVE", "offset": 0},
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Beispielantwort
{
"success": true,
"data": [
{
"id": 1001,
"status": "ACTIVE",
"created_at": "2026-02-25T10:00:00Z",
"product_id": 142,
"phone_number": "+6281234567890",
"amount": 15000,
"otp_code": null,
"otp_received_at": null,
"expires_at": "2026-02-25T10:20:00Z",
"canceled_at": null,
"failed_reason": null
}
]
} /orders/{id} Gibt eine einzelne Bestellung nach ID zurück. Gibt nur Bestellungen des authentifizierten Nutzers zurück.
Pfad-Parameter
| Name | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
id | integer | Ja | Bestell-ID (Pfad-Parameter) |
Beispielanfrage
curl -s https://api.smscode.gg/v1/orders/1001 \
-H "Authorization: Bearer YOUR_API_TOKEN" const res = await fetch("https://api.smscode.gg/v1/orders/1001", {
headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json(); import requests
res = requests.get("https://api.smscode.gg/v1/orders/1001",
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Beispielantwort
{
"success": true,
"data": {
"id": 1001,
"status": "OTP_RECEIVED",
"created_at": "2026-02-25T10:00:00Z",
"product_id": 142,
"phone_number": "+6281234567890",
"amount": 15000,
"otp_code": "123456",
"otp_received_at": "2026-02-25T10:05:00Z",
"expires_at": "2026-02-25T10:20:00Z",
"canceled_at": null,
"failed_reason": null
}
} /orders/active Listet alle aktuell aktiven Bestellungen auf (ACTIVE + OTP_RECEIVED). Verwenden Sie dies, um den OTP-Status abzufragen.
Parameter
Keine
Beispielanfrage
curl -s https://api.smscode.gg/v1/orders/active \
-H "Authorization: Bearer YOUR_API_TOKEN" const res = await fetch("https://api.smscode.gg/v1/orders/active", {
headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json(); import requests
res = requests.get("https://api.smscode.gg/v1/orders/active",
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Beispielantwort
{
"success": true,
"data": [
{
"id": 1001,
"status": "OTP_RECEIVED",
"otp_code": "123456",
"otp_message": "Your verification code is 123456",
"otp_received_at": "2026-02-25T10:05:00Z",
"expires_at": "2026-02-25T10:20:00Z",
"failed_reason": null
},
{
"id": 1002,
"status": "ACTIVE",
"otp_code": null,
"otp_message": null,
"otp_received_at": null,
"expires_at": "2026-02-25T10:50:00Z",
"failed_reason": null
}
]
} /orders/create Erstellt eine neue Bestellung für eine virtuelle Nummer. Guthaben wird automatisch abgebucht. Unterstützt einen optionalen Idempotency-Key-Header, um doppelte Bestellungen bei Netzwerk-Wiederholungen zu verhindern.
Anfragekörper
| Name | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
product_id | integer | Ja | ID des zu bestellenden Produkts |
quantity | integer | Nein | Anzahl (1–100, Standard 1) |
Übergeben Sie einen Idempotency-Key-Header (beliebige eindeutige Zeichenkette), um Anfragen sicher wiederholen zu können, ohne doppelte Bestellungen zu erstellen.
Beispielanfrage
curl -s -X POST https://api.smscode.gg/v1/orders/create \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: unique-request-id-123" \
-d '{"product_id":142,"quantity":1}' const res = await fetch("https://api.smscode.gg/v1/orders/create", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json",
"Idempotency-Key": "unique-request-id-123",
},
body: JSON.stringify({ product_id: 142, quantity: 1 }),
});
const data = await res.json(); import requests
res = requests.post("https://api.smscode.gg/v1/orders/create",
json={"product_id": 142, "quantity": 1},
headers={
"Authorization": "Bearer YOUR_API_TOKEN",
"Idempotency-Key": "unique-request-id-123",
})
data = res.json() Beispielantwort
{
"success": true,
"data": {
"orders": [
{
"id": 1002,
"status": "ACTIVE",
"phone_number": "+6281234567891",
"otp_code": null,
"otp_received_at": null,
"expires_at": "2026-02-25T10:50:00Z",
"failed_reason": null
}
],
"failed_count": 0
}
} /orders/cancel Storniert eine aktive Bestellung. Die Mietkosten werden Ihrem Guthaben gutgeschrieben.
Anfragekörper
| Name | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
id | integer | Ja | Bestell-ID zum Stornieren |
Beispielanfrage
curl -s -X POST https://api.smscode.gg/v1/orders/cancel \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"id":1001}' const res = await fetch("https://api.smscode.gg/v1/orders/cancel", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({ id: 1001 }),
});
const data = await res.json(); import requests
res = requests.post("https://api.smscode.gg/v1/orders/cancel",
json={"id": 1001},
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Beispielantwort
{
"success": true,
"data": {
"order_id": 1001,
"status": "CANCELED",
"refund_amount": 15000,
"new_balance": 515000
}
} /orders/finish Markiert eine Bestellung als abgeschlossen, nachdem der OTP empfangen wurde. Die Nummer wird sofort freigegeben, anstatt auf den Ablauf zu warten.
Anfragekörper
| Name | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
id | integer | Ja | Bestell-ID zum Abschließen |
Beispielanfrage
curl -s -X POST https://api.smscode.gg/v1/orders/finish \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"id":1001}' const res = await fetch("https://api.smscode.gg/v1/orders/finish", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({ id: 1001 }),
});
const data = await res.json(); import requests
res = requests.post("https://api.smscode.gg/v1/orders/finish",
json={"id": 1001},
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Beispielantwort
{
"success": true,
"data": {
"order_id": 1001,
"status": "COMPLETED"
}
} /orders/resend Fordert die Plattform auf, die SMS erneut an die gemietete Nummer zu senden. Nicht alle Plattformen unterstützen den erneuten Versand — prüfen Sie das Feld "resent" in der Antwort.
Anfragekörper
| Name | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
id | integer | Ja | Bestell-ID für erneuten SMS-Versand |
Beispielanfrage
curl -s -X POST https://api.smscode.gg/v1/orders/resend \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"id":1001}' const res = await fetch("https://api.smscode.gg/v1/orders/resend", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({ id: 1001 }),
});
const data = await res.json(); import requests
res = requests.post("https://api.smscode.gg/v1/orders/resend",
json={"id": 1001},
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Beispielantwort
{
"success": true,
"data": {
"order_id": 1001,
"status": "ACTIVE",
"resent": true
}
} /webhook Gibt Ihre aktuelle Webhook-Benachrichtigungskonfiguration zurück.
Parameter
Keine
Beispielanfrage
curl -s https://api.smscode.gg/v1/webhook \
-H "Authorization: Bearer YOUR_API_TOKEN" const res = await fetch("https://api.smscode.gg/v1/webhook", {
headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json(); import requests
res = requests.get("https://api.smscode.gg/v1/webhook",
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Beispielantwort
{
"success": true,
"data": {
"webhook_url": "https://example.com/webhook",
"webhook_secret": "a1b2c3d4e5f6..."
}
} /webhook Aktualisiert Ihre Webhook-URL und/oder Ihr Secret. Ein Secret wird automatisch generiert, wenn Sie zum ersten Mal eine URL festlegen. Senden Sie einen leeren String zum Löschen. Die URL muss HTTPS verwenden.
Anfragekörper
| Name | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
webhook_url | string | Nein | HTTPS-URL für den Empfang von Webhook-Ereignissen (leerer String zum Löschen) |
webhook_secret | string | Nein | Gemeinsames Secret für HMAC-SHA256-Signatur (wird beim ersten Setzen automatisch generiert, falls nicht angegeben) |
Mindestens ein Feld ist erforderlich.
Beispielanfrage
curl -s -X PATCH https://api.smscode.gg/v1/webhook \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"webhook_url":"https://example.com/webhook"}' const res = await fetch("https://api.smscode.gg/v1/webhook", {
method: "PATCH",
headers: {
Authorization: "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({ webhook_url: "https://example.com/webhook" }),
});
const data = await res.json(); import requests
res = requests.patch("https://api.smscode.gg/v1/webhook",
json={"webhook_url": "https://example.com/webhook"},
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Beispielantwort
{
"success": true,
"data": {
"webhook_url": "https://example.com/webhook",
"webhook_secret": "a1b2c3d4e5f6..."
}
} /webhook/test Sendet ein Testereignis an Ihre konfigurierte Webhook-URL. Gibt den HTTP-Statuscode Ihres Servers zurück. Nützlich zur Überprüfung, ob Ihr Endpunkt funktioniert, bevor Sie live gehen.
Parameter
Keine
Beispielanfrage
curl -s -X POST https://api.smscode.gg/v1/webhook/test \
-H "Authorization: Bearer YOUR_API_TOKEN" const res = await fetch("https://api.smscode.gg/v1/webhook/test", {
method: "POST",
headers: { Authorization: "Bearer YOUR_API_TOKEN" },
});
const data = await res.json(); import requests
res = requests.post("https://api.smscode.gg/v1/webhook/test",
headers={"Authorization": "Bearer YOUR_API_TOKEN"})
data = res.json() Beispielantwort
{
"success": true,
"data": {
"status_code": 200
}
} ⟩ Webhook-Benachrichtigungen
Konfigurieren Sie eine Webhook-URL, um Echtzeit-Push-Benachrichtigungen für Bestellereignisse zu erhalten, anstatt zu pollen. Dies ist der empfohlene Ansatz für Bot-Skripte.
Ereignisse
| Ereignis | Auslöser |
|---|---|
order.otp_received | OTP-Code an die gemietete Nummer zugestellt |
order.completed | Bestellung als abgeschlossen markiert (manuell oder durch Ablauf) |
order.expired | Bestellung ohne OTP abgelaufen (Guthaben erstattet) |
order.canceled | Bestellung vom Nutzer storniert (Guthaben erstattet) |
Payload
{
"event": "order.otp_received",
"timestamp": "2026-02-25T12:00:00Z",
"data": {
"order_id": 1001,
"phone_number": "+628123456789",
"otp_code": "1234",
"otp_message": "Your verification code is 1234",
"product_id": 42,
"country": "Indonesia",
"platform": "WhatsApp"
}
} Signaturverifizierung
Jede Webhook-Anfrage enthält einen X-Webhook-Signature-Header mit einer HMAC-SHA256-Signatur des Anfragekörpers, wobei Ihr webhook_secret als Schlüssel verwendet wird:
Verifizieren Sie diese Signatur auf Ihrem Server, um die Authentizität der Anfrage sicherzustellen. Die Zustellung erfolgt nach dem Fire-and-Forget-Prinzip mit einem 3-Sekunden-Timeout und ohne Wiederholungsversuche.
⟩ Rate Limits
API-Anfragen sind pro Endpunkt-Gruppe ratenlimitiert. Bei Überschreitung des Limits wird 429 Too Many Requests mit einem Retry-After-Header zurückgegeben, der angibt, wie viele Sekunden gewartet werden soll.
| Endpunkt-Gruppe | Limit | Zeitfenster |
|---|---|---|
| Katalog (Länder, Dienste, Produkte, Wechselkurs) | 1.200 Anfragen | 60 Sekunden |
| Guthaben | 600 Anfragen | 60 Sekunden |
| Bestellabfragen (Liste, Einzeln, Aktiv) | 1.200 Anfragen | 60 Sekunden |
| Bestellung erstellen | 1.200 Anfragen | 60 Sekunden |
| Bestellung stornieren | 600 Anfragen | 60 Sekunden |
| Bestellaktionen (Abschließen, Erneut senden) | 600 Anfragen | 60 Sekunden |
| Webhook-Konfiguration (Abrufen, Aktualisieren, Testen) | 120 Anfragen | 60 Sekunden |
⟩ Fehlercodes
Fehlerantworten enthalten einen der folgenden Codes in error.code:
| Code | HTTP | Beschreibung |
|---|---|---|
UNAUTHORIZED | 401 | Fehlender oder ungültiger API-Token |
FORBIDDEN | 403 | Zugriff verweigert |
NOT_FOUND | 404 | Ressource nicht gefunden (Bestellung, Wechselkurs usw.) |
CONFLICT | 409 | Doppelte Anfrage oder Ressourcenkonflikt |
INSUFFICIENT_BALANCE | 409 | Unzureichendes Guthaben für die Bestellung |
VALIDATION_ERROR | 422 | Anfrageparameter haben die Validierung nicht bestanden |
RATE_LIMIT_EXCEEDED | 429 | Zu viele Anfragen (prüfen Sie den Retry-After-Header) |
INTERNAL_ERROR | 500 | Interner Serverfehler |
PROVIDER_ERROR | 422 | Vorgelagerter SMS-Anbieter hat die Anfrage abgelehnt |
CANCEL_TOO_EARLY | 409 | Bestellung zu neu zum Stornieren — warten Sie 2 Minuten |
SERVICE_UNAVAILABLE | 503 | Dienst vorübergehend nicht verfügbar (Wartung) |