01Overview
Everything in v2 follows the same handful of conventions. Learn them once and every endpoint behaves the way you expect.
HTTPS + JSON
All requests go to /api/v2 over TLS 1.3. Bodies and responses are JSON with camelCase fields.
Integer minor units
Prices are {"amount": 249900, "currency": "EUR"} — never floats, never formatted strings.
ISO 8601, UTC
Every timestamp is UTC, e.g. 2026-10-17T09:30:00Z. Clinic slots also carry the local offset.
Cursor pagination
Pass limit and cursor. Follow meta.nextCursor until it comes back null.
Idempotency keys
Send an Idempotency-Key on order creation. A retried request never double-charges for a second arm.
Test & live
cp_test_ clients get sandboxed orders that never charge or ship. cp_live_ clients hit the real shop.
02Quickstart
Three requests from zero to a validated implant stack. Pick your language — the choice is remembered.
Get an access token
Exchange your client credentials for a Bearer token, valid for one hour. Keep the secret on your server.
curl -X POST https://cyber-punk.online/oauth/token \
-d grant_type=client_credentials \
-d client_id=$CP_CLIENT_ID \
-d client_secret=$CP_CLIENT_SECRET \
-d scope="catalog:read orders:write"
# → {"access_token": "eyJhbGciOi…", "token_type": "Bearer", "expires_in": 3600}
const res = await fetch("https://cyber-punk.online/oauth/token", {
method: "POST",
body: new URLSearchParams({
grant_type: "client_credentials",
client_id: process.env.CP_CLIENT_ID,
client_secret: process.env.CP_CLIENT_SECRET,
scope: "catalog:read orders:write",
}),
});
const { access_token: token } = await res.json();
import os, requests
r = requests.post("https://cyber-punk.online/oauth/token", data={
"grant_type": "client_credentials",
"client_id": os.environ["CP_CLIENT_ID"],
"client_secret": os.environ["CP_CLIENT_SECRET"],
"scope": "catalog:read orders:write",
})
token = r.json()["access_token"]
Browse the catalog
List implants with filters. Every item carries its full technical profile: neural load, power draw, surgery class and bus.
curl -G https://cyber-punk.online/api/v2/implants \
-H "Authorization: Bearer $CP_TOKEN" \
--data-urlencode "filter[category]=ocular" \
-d limit=20
const url = new URL("https://cyber-punk.online/api/v2/implants");
url.searchParams.set("filter[category]", "ocular");
url.searchParams.set("limit", "20");
const { data, meta } = await fetch(url, {
headers: { Authorization: `Bearer ${token}` },
}).then(r => r.json());
data.forEach(i => console.log(i.sku, i.name, i.specs.neuralLoad));
r = requests.get(
"https://cyber-punk.online/api/v2/implants",
params={"filter[category]": "ocular", "limit": 20},
headers={"Authorization": f"Bearer {token}"},
)
for implant in r.json()["data"]:
print(implant["sku"], implant["name"], implant["specs"]["neuralLoad"])
Validate a stack before checkout
Send the client's neural profile and the implants they want. The engine answers with totals, blocking errors and warnings.
curl -X POST https://cyber-punk.online/api/v2/compatibility/check \
-H "Authorization: Bearer $CP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"neuralProfile": { "interfaceBus": "NL-4", "neuralBudget": 100, "powerBudgetMw": 1200 },
"installed": ["KSL-OCU-KX7"],
"candidates": ["OZU-NEU-SYN3"]
}'
const check = await fetch("https://cyber-punk.online/api/v2/compatibility/check", {
method: "POST",
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
body: JSON.stringify({
neuralProfile: { interfaceBus: "NL-4", neuralBudget: 100, powerBudgetMw: 1200 },
installed: ["KSL-OCU-KX7"],
candidates: ["OZU-NEU-SYN3"],
}),
}).then(r => r.json());
console.log(check.compatible, check.warnings);
r = requests.post(
"https://cyber-punk.online/api/v2/compatibility/check",
headers={"Authorization": f"Bearer {token}"},
json={
"neuralProfile": {"interfaceBus": "NL-4", "neuralBudget": 100, "powerBudgetMw": 1200},
"installed": ["KSL-OCU-KX7"],
"candidates": ["OZU-NEU-SYN3"],
},
)
print(r.json()["compatible"], r.json()["warnings"])
03Authentication
OAuth 2.1 client credentials. Tokens are short-lived and scoped: request only what your integration needs.
GET /api/v2/implants HTTP/1.1
Host: cyber-punk.online
Authorization: Bearer eyJhbGciOiJFZERTQSJ9.eyJzdWIiOiJhY2NfUThOMyJ9.…
Accept: application/json
| Scope | Grants |
|---|---|
| catalog:read | Implants, categories and compatibility checks |
| firmware:read | Firmware releases and signed downloads |
| orders:read orders:write | Carts and orders |
| clinics:read clinics:book | Clinic directory and installation appointments |
| webhooks:manage | Register, list and delete webhook endpoints |
| profile:read profile:write | Account details and the saved neural profile |
04Live console
Pick an endpoint, hit Send, read the response. A fast way to get a feel for the shape of the data.
// Sandbox preview: responses are sample data rendered in your browser, no request leaves this page.
05Neural load simulator
Build a stack and watch the compatibility engine react in real time — exactly the rules POST /compatibility/check applies before every checkout.
06Endpoints
The full reference. Paths are relative to https://cyber-punk.online; filter by keyword, method or scope.
Authentication
POST/oauth/tokenExchange client credentials for an access tokenno auth
Returns a Bearer token valid for 3,600 seconds. Tokens are not refreshable: request a new one when it expires.
| Form field | Type | Description |
|---|---|---|
grant_type | string | Always client_credentials |
client_id | string | cp_test_… or cp_live_… |
client_secret | string | Server-side only, never in a browser or mobile app |
scope | string | Space-separated, e.g. catalog:read orders:write |
Implants
GET/api/v2/implantsList implants in the catalogcatalog:read
Paginated list of implants with their technical profile. Combine filters freely.
| Query | Type | Description |
|---|---|---|
limit | int | 1–100, default 20 |
cursor | string | Value of meta.nextCursor from the previous page |
filter[category] | enum | ocular · neural · dermal · limb · interface · security |
filter[bus] | enum | NL-3 · NL-4 · NL-5 |
filter[maxNeuralLoad] | int | Only implants at or below this NLI |
filter[surgeryClass] | enum | A to D |
sort | string | price · -price · neuralLoad · -updatedAt |
GET/api/v2/implants/{sku}Retrieve one implant with full specscatalog:read
Returns the complete implant object described in the data model, including firmware status and bus compatibility. Unknown SKUs return 404.
GET/api/v2/implants/categoriesCategories with counts and typical NLI rangescatalog:read
Six categories: ocular, neural, dermal, limb, interface and security. Each entry includes the number of SKUs and the typical neural load range, handy for building filters.
Compatibility
POST/api/v2/compatibility/checkValidate an implant stack against a neural profilecatalog:read
Always answers 200 — read compatible, errors and warnings. Orders created with compatibilityCheck: true run the same rules and fail with 422 on any error. Play with the rules in the simulator.
| Body | Type | Description |
|---|---|---|
neuralProfile | object | interfaceBus, neuralBudget, powerBudgetMw |
useSavedProfile | bool | Use the profile stored with PUT /api/v2/me/neural-profile instead |
installed | string[] | SKUs the client already runs |
candidates | string[] | SKUs they want to add |
Firmware
GET/api/v2/implants/{sku}/firmwareList firmware releases per channelfirmware:read
Optional channel query: stable, beta or lts. Each release carries its SHA-256 checksum and Ed25519 signature.
GET/api/v2/firmware/{releaseId}/downloadDownload a firmware imagefirmware:read
Responds 302 to a signed URL valid for 10 minutes. Verify the signature before flashing — see Firmware.
Carts & orders
POST/api/v2/cartsCreate a server-side cartorders:write
Returns a cartId. Carts expire after 72 hours of inactivity.
POST/api/v2/carts/{cartId}/itemsAdd an implant to a cartorders:write
Body: sku and quantity (default 1). Prices are locked for 30 minutes after the item is added.
POST/api/v2/ordersPlace an order from a cartorders:write
Requires an Idempotency-Key header (UUID v4, kept 24 h). Live orders answer 503 live_orders_paused until the shop reopens on 27 June 2027; test-mode orders work now.
| Body | Type | Description |
|---|---|---|
cartId | string | Cart to convert |
clinicId | string | Installation clinic, must be certified for every surgery class in the cart |
compatibilityCheck | bool | Default true. Turning it off requires a clinic override token |
GET/api/v2/orders/{orderId}Retrieve an order and its shipping statusorders:read
Prefer the order.* webhooks over polling this endpoint.
Clinics
GET/api/v2/clinicsSearch the certified clinic networkclinics:read
43 partner clinics in 31 cities. Filter with filter[city] (three-letter code, e.g. PAR) and filter[surgeryClass].
POST/api/v2/clinics/{clinicId}/appointmentsBook an installation slotclinics:book
Body: orderId and slot (ISO 8601 with offset). Returns 409 clinic_not_certified if the clinic can't perform a surgery class in the order.
Webhooks
POST/api/v2/webhooksRegister an HTTPS endpointwebhooks:manage
Body: url (HTTPS only) and events. The signing secret is returned once — store it immediately.
GET/api/v2/webhooksList registered webhookswebhooks:manage
Includes the last delivery status and failure count for each endpoint.
DELETE/api/v2/webhooks/{webhookId}Remove a webhookwebhooks:manage
Pending deliveries are dropped. Returns 204.
Account
GET/api/v2/meCurrent account, mode and granted scopesprofile:read
PUT/api/v2/me/neural-profileSave a neural profile for future checksprofile:write
Body: interfaceBus, neuralBudget, powerBudgetMw and installed. Encrypted at rest; upload it once, then pass useSavedProfile: true to compatibility checks.
System
GET/api/v2/statusAPI version, latency and shop statusno auth
Public. Reports whether live orders are open — useful to show a maintenance banner in your own storefront.
Try it in the console →// No endpoint matches that signal.
07Data model
The implant object is the heart of v2. Every field below is returned by GET /api/v2/implants/{sku}.
- neuralLoad · int 0–100
- Neural Load Index (NLI): share of the nervous system's processing headroom the implant consumes. Stacks above 85% of the budget warn, above 100% are rejected.
- interfaceBus · enum
NL-3(legacy),NL-4(current standard) orNL-5(high-bandwidth, needed for full-sensory implants).- powerDrawMw · int
- Continuous draw from the subdermal bio-cell, in milliwatts. Under 20% headroom triggers a warning.
- bioRejectionRisk · enum
low·moderate·high, from material biocompatibility. Network-wide rejection rate: 0.3%.- surgeryClass · A–D
- A: outpatient. B: minor invasive. C: spinal or cranial. D: full-limb replacement. Clinics only book classes they're certified for.
- firmware · object
- Current
version,channelandotaSupported. Releases live under/firmware. - iceRating · int 1–5 | null
- Security implants only: tier of intrusion countermeasures protecting the neural port.
- compatibleWith · string[]
- Buses the implant runs on. Empty for passive implants, which fit any profile.
{
"data": {
"sku": "KSL-OCU-KX7",
"name": "KX-7 Ocular Overlay",
"category": "ocular",
"manufacturer": "Kessler Neuroworks",
"price": { "amount": 249900, "currency": "EUR" },
"stock": { "status": "preorder", "availableFrom": "2027-06-27" },
"specs": {
"interfaceBus": "NL-4",
"neuralLoad": 18,
"powerDrawMw": 340,
"bioRejectionRisk": "low",
"surgeryClass": "B",
"iceRating": null,
"firmware": { "version": "4.2.1", "channel": "stable", "otaSupported": true }
},
"compatibleWith": ["NL-4", "NL-5"],
"legacy": false,
"updatedAt": "2026-10-09T08:00:00Z"
},
"meta": { "apiVersion": "2.4.1", "requestId": "req_01JAX9F3K2" }
}
08Firmware vault
3,912 signed images across every implant in the catalog. Your chrome only ever runs code we can vouch for — as long as you check.
Default channel
Signed security patches keep flowing OTA, even during the storefront maintenance.
Opt-in early access
New features weeks before stable. Expect the occasional visual glitch.
Long-term support
18 months of fixes on a frozen feature set. Built for clinics and fleets.
import crypto from "node:crypto";
// release = one item from GET /api/v2/implants/{sku}/firmware
const digest = crypto.createHash("sha256").update(image).digest("hex");
if (digest !== release.sha256) throw new Error("Checksum mismatch. Do not flash.");
const signature = Buffer.from(release.signature.replace("ed25519:", ""), "base64");
const valid = crypto.verify(null, image, CP_FIRMWARE_PUBLIC_KEY, signature);
if (!valid) throw new Error("Unsigned chrome. Do not flash.");
09Webhooks
Stop polling. We push events to your HTTPS endpoint, retry with exponential backoff for 24 hours, and sign every delivery.
| Event | Fires when |
|---|---|
order.created | An order is placed, in test or live mode |
order.shipped | The order leaves the warehouse, with tracking |
order.delivered | Delivered to the clinic or the client |
appointment.confirmed | A clinic confirms an installation slot |
appointment.rescheduled | The clinic moves a slot |
implant.firmware.released | A new release lands on a channel you follow |
implant.recalled | A manufacturer recall — notify affected clients |
clinic.certified | A clinic gains a new surgery class |
POST /hooks/cp HTTP/1.1
Content-Type: application/json
CP-Event: implant.firmware.released
CP-Signature: t=1792195200,sha256=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd
{
"id": "evt_01JB2Q7XK4",
"type": "implant.firmware.released",
"createdAt": "2026-10-09T08:00:04Z",
"mode": "live",
"data": { "sku": "KSL-OCU-KX7", "releaseId": "fw_kx7_421", "channel": "stable", "version": "4.2.1" }
}
import crypto from "node:crypto";
export function verifyCpSignature(rawBody, header, secret, toleranceSec = 300) {
const parts = Object.fromEntries(header.split(",").map(p => p.split("=")));
const t = Number(parts.t);
if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSec) return false; // replay guard
const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest();
const given = Buffer.from(parts.sha256 || "", "hex");
return given.length === expected.length && crypto.timingSafeEqual(given, expected);
}
10Errors & limits
Errors use real HTTP statuses and an application/problem+json body (RFC 9457) with a stable code you can switch on.
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | Malformed body or query parameter |
| 401 | invalid_token | Missing or expired token |
| 403 | insufficient_scope | Token lacks the scope for this endpoint |
| 404 | not_found | Unknown SKU, order, clinic or webhook |
| 409 | idempotency_conflict | Same key reused with a different body |
| 409 | clinic_not_certified | Clinic can't perform a surgery class in the order |
| 422 | NEURAL_LOAD_EXCEEDED · POWER_BUDGET_EXCEEDED · BUS_INCOMPATIBLE | Order blocked by the compatibility engine |
| 429 | rate_limited | Slow down; honour Retry-After |
| 503 | live_orders_paused | Live orders before the 27 June 2027 reopening |
{
"type": "https://cyber-punk.online/docs/errors/neural-load-exceeded",
"title": "Neural load exceeded",
"status": 422,
"code": "NEURAL_LOAD_EXCEEDED",
"detail": "Stack totals 112 NLI against a budget of 100.",
"requestId": "req_01JB2R0C8M"
}
HTTP/1.1 200 OK
RateLimit-Limit: 600 # requests per minute, per token
RateLimit-Remaining: 587
RateLimit-Reset: 42 # seconds until the window resets
Retry-After: 42 # only on 429
11Changelog
Additive changes only within v2. Nothing here breaks an existing integration.
- v2.4.1 · 02 Oct 2026
Local clinic times
Clinic slots now carry the local UTC offset alongside the UTC timestamp.
- v2.4.0 · 15 Sep 2026
ICE ratings & NLI filter
New
iceRatingfield on security implants andfilter[maxNeuralLoad]on the catalog. - v2.3.0 · 08 Jul 2026
Saved neural profiles
PUT /api/v2/me/neural-profileanduseSavedProfileon compatibility checks. - v2.2.0 · 20 May 2026
LTS firmware channel
18-month support channel for clinics and fleets, plus
implant.recalledwebhooks. - v2.0.0 · 03 Mar 2026
General availability
OAuth 2.1, compatibility engine, signed firmware vault and webhooks go live.