language
Automatically detected

We have pre-selected English and US Dollar ($) for you.

Log In
softwarebay.de
softwarebay.de

info Overview

Base URL
softwarebay.de/api/v1
Format
JSON (UTF-8)
Authentication
Bearer Token
Rate Limit
60 req/min
TLS
HTTPS only
Version
v1.0 · Stable

The SoftwareBay REST API enables business customers to programmatically access order data, license codes and download URLs. Typical use cases include ERP integration, automated license distribution, accounting exports and audit workflows.

business
Available for business customers only. API keys can only be created for accounts with a registered company or VAT ID. Go to customer account →
security
All requests run over HTTPS. Keys are stored server-side as SHA-256 hashes and are never shown in plain text after creation.

lock Authentication

Every API request must pass the key in the Authorization header as a Bearer token:

HTTP Header
Authorization: Bearer sb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Accept: application/json
warning
Keys belong to one account. Never share your key. If compromised, revoke it immediately in your customer account.

error_outline Error Codes

All error responses contain an error field with a human-readable description.

Error Response
{
  "status": 401,
  "error": "Unauthorized – invalid or inactive API key"
}
HTTP CodeMeaningSolution
400Invalid requestCheck parameters
401Key invalid or revokedCheck key in account
403Not a business accountAdd company / VAT ID in profile
404Order not foundCheck order ID; does it belong to your account?
429Rate limit exceededWait – max. 60 requests/minute
500Internal server errorPlease contact support

speed Rate Limiting

The limit is 60 requests per minute per API key. When exceeded, all further requests respond with 429 Too Many Requests. The window resets automatically after 60 seconds.

tips_and_updates
For bulk exports, we recommend the pagination export with a controlled delay between requests.

api Endpoints

GET /api/v1/me Query authenticated user expand_more

Returns basic information about the user of the API key. Suitable for connection testing and key verification.

Response Schema

FieldTypeDescription
user_idintegerInternal user ID
emailstringAccount email address
namestringFirst and last name
companystringCompany name
vat_idstringVAT identification number
api_versionstringCurrent API version

Example Response

{
  "status": 200,
  "data": {
    "user_id": 1042,
    "email": "firma@beispiel.de",
    "name": "Max Mustermann",
    "company": "Musterfirma GmbH",
    "vat_id": "DE123456789",
    "api_version": "1.0"
  }
}
GET /api/v1/orders Order list (paginated) expand_more

Returns a paginated list of all orders for the account, sorted descending by order date.

Query Parameters

ParameterTypeRequiredDescription
pageintegerOptionalPage number (default: 1)
per_pageintegerOptionalEntries per page, 1–50 (default: 20)
statusstringOptionalFilter by status — ausstehend | bezahlt | abgeschlossen | storniert

Response Schema

FieldTypeDescription
orders[]arrayOrder list (paginated)
orders[].idintegerInternal order ID
orders[].bestellnummerstringHuman-readable order number
orders[].statusstringOrder status
orders[].zahlungsstatusstringPayment status
orders[].gesamtpreis_bruttodecimalTotal amount (gross)
orders[].waehrungstringISO 4217 (e.g. EUR)
orders[].created_atdatetimeOrder timestamp (UTC)
paginationobjectPagination data
pagination.pageintegerCurrent page
pagination.per_pageintegerEntries per page
pagination.totalintegerTotal order count
pagination.pagesintegerTotal page count

Example Response

{
  "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
    }
  }
}
GET /api/v1/orders/{id} Order incl. license codes expand_more

Returns a complete order including all items, decrypted license codes and download URLs. License codes are only available for orders with status paid or completed.

Path Parameters

ParameterTypeRequiredDescription
idintegerRequiredInternal order ID (from GET /orders)

Response Schema (excerpt)

FieldTypeDescription
items[].license_codes[]arrayLicense codes for the order item
license_codes[].license_keystringDecrypted license key
license_codes[].code_typstringCode type — retail | volumen | account | abo
license_codes[].download_url_64string|nullDownload URL (64-bit)
license_codes[].download_url_32string|nullDownload URL (32-bit)
license_codes[].aktivierungen_bestellungintegerNumber of allowed activations
billing_addressobjectBilling address

Example Response

{
  "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
          }
        ]
      }
    ]
  }
}

code Code Examples

Basic API call

# 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");

Fetch all orders paginated

// 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;
}

Fetch completed orders only

cURL
curl "https://softwarebay.de/api/v1/orders?status=abgeschlossen&per_page=50" \
  -H "Authorization: Bearer sb_live_YOUR_KEY"

Robust error handling

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);
  }
}

Bulk export: all license codes as 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")

science Live API Tester

Test your API key directly in the browser. The request runs through your own connection — the key is never sent to our servers.

terminal Live API Tester

API Key
Endpoint
shield Your key never leaves this page – the request is sent directly from your browser.

vpn_key Manage API Keys

Keys are created in the customer account (max. 5 per account) and can be revoked at any time. A key that has been created cannot be restored.

manage_accounts Go to API section in customer account
Live support available
Lara Maria K.
Lara Maria K.
check_circle Timisoara
Hello! I am Lara Maria. Do you have questions about our products or need help?
chat_bubble