Documentație API
SoftwareBay REST API v1 — Referință completă pentru dezvoltatori
Prezentare generală
API-ul REST SoftwareBay permite clienților business să acceseze programatic datele comenzilor, codurile de licență și URL-urile de descărcare. Cazuri tipice de utilizare includ integrarea ERP, distribuția automată de licențe, exporturi contabile și fluxuri de audit.
Autentificare
Fiecare cerere API trebuie să transmită cheia în antetul Authorization ca token Bearer:
Authorization: Bearer sb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Accept: application/json
Coduri de eroare
Toate răspunsurile de eroare conțin un câmp error cu o descriere lizibilă.
{
"status": 401,
"error": "Unauthorized – invalid or inactive API key"
}
| Cod HTTP | Semnificație | Soluție |
|---|---|---|
| 400 | Cerere invalidă | Verificați parametrii |
| 401 | Cheie invalidă sau revocată | Verificați cheia în cont |
| 403 | Nu este cont business | Adăugați compania / codul TVA în profil |
| 404 | Comandă negăsită | Verificați ID-ul comenzii; aparține contului dvs.? |
| 429 | Limita de rată depășită | Așteptați – max. 60 cereri/minut |
| 500 | Eroare internă a serverului | Contactați suportul |
Limitarea ratei
Limita este de 60 de cereri pe minut per cheie API. La depășire, toate cererile ulterioare răspund cu 429 Too Many Requests. Fereastra se resetează automat după 60 de secunde.
Endpoint-uri
Returnează informații de bază despre utilizatorul cheii API. Potrivit pentru verificarea conexiunii și validarea cheii.
Schema răspunsului
| Câmp | Tip | Descriere |
|---|---|---|
| user_id | integer | ID intern utilizator |
| string | Adresa de e-mail a contului | |
| name | string | Prenume și nume |
| company | string | Numele companiei |
| vat_id | string | Cod de identificare TVA |
| api_version | string | Versiunea curentă a API-ului |
Exemplu de răspuns
{
"status": 200,
"data": {
"user_id": 1042,
"email": "firma@beispiel.de",
"name": "Max Mustermann",
"company": "Musterfirma GmbH",
"vat_id": "DE123456789",
"api_version": "1.0"
}
}Returnează o listă paginată a tuturor comenzilor contului, sortate descendent după data comenzii.
Parametri de interogare
| Parametru | Tip | Obligatoriu | Descriere |
|---|---|---|---|
| page | integer | Opțional | Numărul paginii (implicit: 1) |
| per_page | integer | Opțional | Intrări pe pagină, 1–50 (implicit: 20) |
| status | string | Opțional | Filtrare după status — ausstehend | bezahlt | abgeschlossen | storniert |
Schema răspunsului
| Câmp | Tip | Descriere |
|---|---|---|
| orders[] | array | Listă comenzi (paginată) |
| orders[].id | integer | ID intern comandă |
| orders[].bestellnummer | string | Număr de comandă lizibil |
| orders[].status | string | Status comandă |
| orders[].zahlungsstatus | string | Status plată |
| orders[].gesamtpreis_brutto | decimal | Total brut |
| orders[].waehrung | string | ISO 4217 (ex. EUR) |
| orders[].created_at | datetime | Momentul comenzii (UTC) |
| pagination | object | Date de paginare |
| pagination.page | integer | Pagina curentă |
| pagination.per_page | integer | Intrări pe pagină |
| pagination.total | integer | Număr total comenzi |
| pagination.pages | integer | Număr total pagini |
Exemplu de răspuns
{
"status": 200,
"data": {
"orders": [
{
"id": 12345,
"bestellnummer": "S24DXG9F8JK2",
"status": "abgeschlossen",
"zahlungsstatus": "bezahlt",
"gesamtpreis_brutto": "29.99",
"waehrung": "EUR",
"created_at": "2026-04-18 10:23:45",
"lieferstatus": "vollstaendig"
}
],
"pagination": {
"page": 1,
"per_page": 20,
"total": 47,
"pages": 3
}
}
}Returnează o comandă completă inclusiv toate pozițiile, codurile de licență decriptate și URL-urile de descărcare. Codurile de licență sunt disponibile doar pentru comenzile cu status plătit sau finalizat.
Parametri de cale
| Parametru | Tip | Obligatoriu | Descriere |
|---|---|---|---|
| id | integer | Obligatoriu | ID intern comandă (din GET /orders) |
Schema răspunsului (extras)
| Câmp | Tip | Descriere |
|---|---|---|
| items[].license_codes[] | array | Coduri de licență pentru poziția comenzii |
| license_codes[].license_key | string | Cheie de licență decriptată |
| license_codes[].code_typ | string | Tipul codului — retail | volumen | account | abo |
| license_codes[].download_url_64 | string|null | URL descărcare (64-bit) |
| license_codes[].download_url_32 | string|null | URL descărcare (32-bit) |
| license_codes[].aktivierungen_bestellung | integer | Numărul de activări permise |
| billing_address | object | Adresă de facturare |
Exemplu de răspuns
{
"status": 200,
"data": {
"id": 12345,
"bestellnummer": "S24DXG9F8JK2",
"status": "abgeschlossen",
"gesamtpreis_brutto": "29.99",
"waehrung": "EUR",
"items": [
{
"id": 8821,
"product_name": "Microsoft Office 2021 Professional Plus",
"menge": 1,
"einzelpreis_brutto": "29.99",
"license_codes": [
{
"id": 5501,
"code_typ": "retail",
"license_key": "XXXXX-XXXXX-XXXXX-XXXXX-XXXXX",
"download_url_64": "https://download.microsoft.com/...",
"download_url_32": null,
"aktivierungen_bestellung": 1
}
]
}
]
}
}Exemple de cod
Apel API de bază
# Verify account
curl -X GET "https://softwarebay.de/api/v1/me" \
-H "Authorization: Bearer sb_live_YOUR_KEY"
# All orders (first page)
curl -X GET "https://softwarebay.de/api/v1/orders" \
-H "Authorization: Bearer sb_live_YOUR_KEY"
# Order #12345 with license codes
curl -X GET "https://softwarebay.de/api/v1/orders/12345" \
-H "Authorization: Bearer sb_live_YOUR_KEY"define('SB_API_KEY', 'sb_live_YOUR_KEY');
define('SB_API_URL', 'https://softwarebay.de/api/v1');
function sbApi($path) {
$ch = curl_init(SB_API_URL . $path);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . SB_API_KEY,
'Accept: application/json',
],
]);
$json = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status !== 200) throw new RuntimeException("API Error $status");
return json_decode($json, true)['data'];
}
$user = sbApi('/me');
$orders = sbApi('/orders');
$order = sbApi('/orders/12345');import requests
API_KEY = "sb_live_YOUR_KEY"
BASE = "https://softwarebay.de/api/v1"
headers = {"Authorization": f"Bearer {API_KEY}"}
def sb_api(path, params=None):
r = requests.get(BASE + path, headers=headers, params=params)
r.raise_for_status()
return r.json()["data"]
user = sb_api("/me")
orders = sb_api("/orders")
order = sb_api("/orders/12345")const API_KEY = 'sb_live_YOUR_KEY';
const BASE = 'https://softwarebay.de/api/v1';
async function sbApi(path) {
const r = await fetch(BASE + path, {
headers: { 'Authorization': `Bearer ${API_KEY}` }
});
if (!r.ok) throw new Error(`API ${r.status}`);
return (await r.json()).data;
}
const user = await sbApi('/me');
const orders = await sbApi('/orders');
const order = await sbApi('/orders/12345');using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", "sb_live_YOUR_KEY");
async Task<JsonElement> SbApi(string path) {
var json = await client.GetStringAsync($"https://softwarebay.de/api/v1{path}");
return JsonDocument.Parse(json).RootElement.GetProperty("data");
}
var user = await SbApi("/me");
var orders = await SbApi("/orders");
var order = await SbApi("/orders/12345");Preluarea tuturor comenzilor cu paginare
// Collect all pages
$all = []; $page = 1;
do {
$result = sbApi("/orders?page={$page}&per_page=50");
$all = array_merge($all, $result['orders']);
$pages = $result['pagination']['pages'];
$page++;
usleep(200000); // 200ms delay – respect rate limit
} while ($page <= $pages);
echo count($all) . " orders loaded";import time
def all_orders():
orders, page = [], 1
while True:
data = sb_api("/orders", {"page": page, "per_page": 50})
orders.extend(data["orders"])
if page >= data["pagination"]["pages"]: break
page += 1
time.sleep(0.2) # respect rate limit
return orders
result = all_orders()
print(f"{len(result)} orders loaded")async function allOrders() {
const all = []; let page = 1;
do {
const data = await sbApi(`/orders?page=${page}&per_page=50`);
all.push(...data.orders);
if (page >= data.pagination.pages) break;
page++;
await new Promise(r => setTimeout(r, 200));
} while (true);
return all;
}Preluarea doar a comenzilor finalizate
curl "https://softwarebay.de/api/v1/orders?status=abgeschlossen&per_page=50" \
-H "Authorization: Bearer sb_live_YOUR_KEY"
Gestionare robustă a erorilor
function sbApiSafe($path, $retry = 3) {
for ($i = 0; $i < $retry; $i++) {
$ch = curl_init(SB_API_URL . $path);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . SB_API_KEY],
CURLOPT_TIMEOUT => 15,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status === 200) return json_decode($body, true)['data'];
if ($status === 429) { sleep(60); continue; }
$err = json_decode($body, true)['error'] ?? "HTTP $status";
throw new RuntimeException("API Error: $err");
}
throw new RuntimeException("Rate limit not resolved after $retry attempts");
}import time, requests
def sb_api_safe(path, params=None, retries=3):
for attempt in range(retries):
r = requests.get(BASE + path, headers=headers, params=params, timeout=15)
if r.status_code == 200: return r.json()["data"]
if r.status_code == 429:
time.sleep(60)
continue
r.raise_for_status()
raise RuntimeError("Rate limit not resolved")async function sbApiSafe(path, retries = 3) {
for (let i = 0; i < retries; i++) {
const r = await fetch(BASE + path, {
headers: { 'Authorization': `Bearer ${API_KEY}` }
});
if (r.ok) return (await r.json()).data;
if (r.status === 429) { await new Promise(res => setTimeout(res, 60000)); continue; }
const err = (await r.json()).error ?? `HTTP ${r.status}`;
throw new Error(err);
}
}Export în masă: toate codurile de licență ca CSV
// Export all completed orders → CSV with license codes
$fp = fopen('licenses.csv', 'w');
fputcsv($fp, ['Order#', 'Product', 'License Key', 'Type', 'Download']);
$page = 1;
do {
$list = sbApi("/orders?status=abgeschlossen&per_page=50&page={$page}");
foreach ($list['orders'] as $o) {
$order = sbApi("/orders/{$o['id']}");
foreach ($order['items'] as $item) {
foreach ($item['license_codes'] as $code) {
fputcsv($fp, [
$order['bestellnummer'],
$item['product_name'],
$code['license_key'],
$code['code_typ'],
$code['download_url_64'] ?? '',
]);
}
}
usleep(100000);
}
$page++;
} while ($page <= $list['pagination']['pages']);
fclose($fp);
echo "Export complete: licenses.csv";import csv, time
with open("licenses.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["Order#", "Product", "License Key", "Type", "Download"])
page = 1
while True:
data = sb_api("/orders", {"status": "abgeschlossen", "per_page": 50, "page": page})
for o in data["orders"]:
order = sb_api(f"/orders/{o['id']}")
for item in order["items"]:
for code in item["license_codes"]:
writer.writerow([
order["bestellnummer"], item["product_name"],
code["license_key"], code["code_typ"],
code.get("download_url_64", ""),
])
time.sleep(0.1)
if page >= data["pagination"]["pages"]: break
page += 1
print("Export complete: licenses.csv")Tester API Live
Testați cheia API direct în browser. Cererea rulează prin propria dvs. conexiune — cheia nu este trimisă la serverele noastre.
Tester API Live
Gestionare chei API
Cheile sunt create în contul clientului (max. 5 per cont) și pot fi revocate oricând. O cheie creată nu poate fi restaurată.
Mergi la secțiunea API din contul clientului