{"activeVersionTag":"latest","latestAvailableVersionTag":"latest","collection":{"info":{"_postman_id":"e0a8eaed-c5c8-40e0-87bf-c84834cbeb2e","name":"Whitelabel","description":"# API URL:\n\n- **Sandbox**: `https://sandbox.zvxlab.com/api/v1/tenant`\n    \n- **Production**: `https://api.zvxlab.com/api/v1/tenant`\n    \n\n## Authentication\n\nThe platform uses a three-layer authentication model:\n\n> Client - \\[mTLS\\] => NGINX - \\[API Key → JWT\\] => App - \\[Bearer JWT\\] => Business API \n  \n\n### Layer 1 — mTLS (Transport)\n\nNGINX validates the client TLS certificate against the platform CA. On success it forwards:\n\n| Header | Value |\n| --- | --- |\n| `X-SSL-Client-Fingerprint` |  |\n\n> **Dev bypass:** `MTLS_ENABLED=false` skips mTLS validation (non-production only). \n  \n\nDont forget to add your client certificates in Postman: `Settings -> Certificates`\n\n### Layer 2 — API Key\n\n`api_key` is provisioned once via the Admin API. Send them to `POST /tenant/auth/token` to obtain a Bearer JWT.\n\n### Layer 3 — Bearer JWT\n\nShort-lived JWT (default TTL: 1 hour). Include it as `Authorization: Bearer {{access_token}}` on every business request. The `token` request in the Auth folder saves it automatically to the `access_token` variable.\n\n# Client TLS Certificate\n\nYou must present a client certificate on every request: NGINX rejects the TLS handshake outright if the certificate is missing, expired, or not chained to our CA, and the application backend additionally requires the header `X-SSL-Client-Fingerprint:` that NGINX forwards on success. The fingerprint we expect is the SHA-256 hash of the DER-encoded leaf certificate, lowercase hex, no colons (the binding check normalizes input, but please send it pre-normalized). The same certificate must be presented on `POST tenant/auth/token` and on every subsequent business call.\n\n## How to issue a certificate\n\nGenerate a long-lived RSA-2048 or ECDSA P-256 keypair on your side and produce a Certificate Signing Request (CSR). The private key must never leave your infrastructure — we only need the CSR. Recommended one-liner:\n\n``` bash\n openssl req -new -newkey rsa:2048 -nodes \\\n    -keyout partner.key \\\n    -out partner.csr \\\n    -subj \"/CN=<your-tenant-slug>.partner.<our-domain>/O=<your legal name>/C=<XX>\"\n\n ```\n\nKeep `partner.key` permission-locked ( `chmod 600` ) and back it up under your KMS/HSM policy — there is no recovery path if it leaks, only revoke-and-reissue\n\n## What to send\n\nSubmit the following to your integration contact:\n\n1. The CSR file ( `partner.csr` ) — text/PEM.\n    \n2. Target environment (sandbox or production).\n    \n3. A technical contact email for expiry notifications.\n    \n\nWe will sign the CSR against the platform CA, register the resulting certificate and return the signed PEM plus the CA chain. From that moment the certificate is pinned to your tenant: any other certificate — even one signed by the same CA will be rejected at the auth step. Certificates are valid for 12 months; we will contact the technical email 30 days before expiry to start the re-issuance cycle.\n\nTo revoke early (key compromise, staff turnover), notify your integration contact and we will flip the record to revoked immediately.\n\n## Computing the fingerprint\n\nThe fingerprint is `sha256(DER(leaf-cert))` rendered as lowercase hex with no separators. A few ways to produce it:\n\n``` bash\n openssl x509 -in partner.crt -outform DER \\\n    | openssl dgst -sha256 \\\n    | awk '{print $2}'\n  # → e.g. 3f9a2c1b8d...e7\n\n ```\n\nOr directly, then strip the formatting NGINX-style:\n\n``` bash\n openssl x509 -in partner.crt -noout -fingerprint -sha256 \\\n    | sed 's/^.*=//; s/://g' \\\n    | tr 'A-F' 'a-f'\n\n ```\n\n### Python example\n\n``` python\n  import hashlib\n  from cryptography import x509\n  from cryptography.hazmat.primitives import serialization\n  with open(\"partner.crt\", \"rb\") as f:\n      cert = x509.load_pem_x509_certificate(f.read())\n  der = cert.public_bytes(serialization.Encoding.DER)\n  fingerprint = hashlib.sha256(der).hexdigest()  # already lowercase, no colons\n  print(fingerprint)\n\n ```\n\n### Node.js example\n\n``` javascript\n import { readFileSync } from \"node:fs\";\n import { X509Certificate, createHash } from \"node:crypto\";\n const cert = new X509Certificate(readFileSync(\"partner.crt\"));\n const fingerprint = createHash(\"sha256\").update(cert.raw).digest(\"hex\");\n console.log(fingerprint);\n\n ```\n\n### Go example\n\n``` go\npackage main\nimport (\n        \"crypto/sha256\"\n        \"crypto/x509\"\n        \"encoding/hex\"\n        \"encoding/pem\"\n        \"fmt\"\n        \"os\"\n)\nfunc main() {\n        raw, _ := os.ReadFile(\"partner.crt\")\n        block, _ := pem.Decode(raw)\n        cert, _ := x509.ParseCertificate(block.Bytes)\n        sum := sha256.Sum256(cert.Raw)\n        fmt.Println(hex.EncodeToString(sum[:]))\n}\n\n ```","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","isPublicCollection":false,"owner":"54606592","team":15727855,"collectionId":"e0a8eaed-c5c8-40e0-87bf-c84834cbeb2e","publishedId":"2sBXqNkJ6c","public":true,"publicUrl":"https://docs.cards.zvxlab.com","privateUrl":"https://go.postman.co/documentation/54606592-e0a8eaed-c5c8-40e0-87bf-c84834cbeb2e","customColor":{"top-bar":"e8ecf1","right-sidebar":"303030","highlight":"667eea"},"documentationLayout":"classic-double-column","customisation":{"metaTags":[{"name":"description","value":""},{"name":"title","value":"White Label API"}],"appearance":{"default":"light","themes":[{"name":"dark","logo":null,"colors":{"top-bar":"212121","right-sidebar":"303030","highlight":"FF6C37"}},{"name":"light","logo":null,"colors":{"top-bar":"e8ecf1","right-sidebar":"303030","highlight":"667eea"}}]}},"version":"8.11.6","publishDate":"2026-05-08T09:11:41.000Z","activeVersionTag":"latest","documentationTheme":"light","metaTags":{"title":"White Label API","description":""},"logos":{"logoLight":null,"logoDark":null}},"statusCode":200},"environments":[{"name":"sandbox","id":"16996205-c16a-435d-a412-90cd7244d2f7","owner":"54606592","values":[{"key":"base_url","value":"https://sandbox.api.example.com","type":"default","enabled":true},{"key":"key_id","value":"","type":"default","enabled":true},{"key":"key_secret","value":"","type":"secret","enabled":true},{"key":"access_token","value":"","type":"secret","enabled":true},{"key":"card_uuid","value":"","type":"default","enabled":true},{"key":"external_user_id","value":"ext-user-001","type":"default","enabled":true},{"key":"product_uuid","value":"","type":"default","enabled":true},{"key":"partner_webhook_url","value":"https://your-domain.example.com/webhooks/neobank","type":"default","enabled":true},{"key":"webhookUrl","value":"","type":"default","enabled":true}],"published":true}],"user":{"authenticated":false,"permissions":{"publish":false}},"run":{"button":{"js":"https://run.pstmn.io/button.js","css":"https://run.pstmn.io/button.css"}},"web":"https://www.getpostman.com/","team":{"logo":"https://res.cloudinary.com/postman/image/upload/t_team_logo_pubdoc/v1/team/9fa38ada997ac7557f9df4375ee8efdc895c6e7212c611fc654a7cd43176e0fc","favicon":"https://zvxlab.com/favicon.ico"},"isEnvFetchError":false,"languages":"[{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"HttpClient\"},{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"RestSharp\"},{\"key\":\"curl\",\"label\":\"cURL\",\"variant\":\"cURL\"},{\"key\":\"dart\",\"label\":\"Dart\",\"variant\":\"http\"},{\"key\":\"go\",\"label\":\"Go\",\"variant\":\"Native\"},{\"key\":\"http\",\"label\":\"HTTP\",\"variant\":\"HTTP\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"OkHttp\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"Unirest\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"Fetch\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"jQuery\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"XHR\"},{\"key\":\"c\",\"label\":\"C\",\"variant\":\"libcurl\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Axios\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Native\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Request\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Unirest\"},{\"key\":\"objective-c\",\"label\":\"Objective-C\",\"variant\":\"NSURLSession\"},{\"key\":\"ocaml\",\"label\":\"OCaml\",\"variant\":\"Cohttp\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"cURL\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"Guzzle\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"HTTP_Request2\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"pecl_http\"},{\"key\":\"powershell\",\"label\":\"PowerShell\",\"variant\":\"RestMethod\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"http.client\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"Requests\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"httr\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"RCurl\"},{\"key\":\"ruby\",\"label\":\"Ruby\",\"variant\":\"Net::HTTP\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"Httpie\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"wget\"},{\"key\":\"swift\",\"label\":\"Swift\",\"variant\":\"URLSession\"}]","languageSettings":[{"key":"csharp","label":"C#","variant":"HttpClient"},{"key":"csharp","label":"C#","variant":"RestSharp"},{"key":"curl","label":"cURL","variant":"cURL"},{"key":"dart","label":"Dart","variant":"http"},{"key":"go","label":"Go","variant":"Native"},{"key":"http","label":"HTTP","variant":"HTTP"},{"key":"java","label":"Java","variant":"OkHttp"},{"key":"java","label":"Java","variant":"Unirest"},{"key":"javascript","label":"JavaScript","variant":"Fetch"},{"key":"javascript","label":"JavaScript","variant":"jQuery"},{"key":"javascript","label":"JavaScript","variant":"XHR"},{"key":"c","label":"C","variant":"libcurl"},{"key":"nodejs","label":"NodeJs","variant":"Axios"},{"key":"nodejs","label":"NodeJs","variant":"Native"},{"key":"nodejs","label":"NodeJs","variant":"Request"},{"key":"nodejs","label":"NodeJs","variant":"Unirest"},{"key":"objective-c","label":"Objective-C","variant":"NSURLSession"},{"key":"ocaml","label":"OCaml","variant":"Cohttp"},{"key":"php","label":"PHP","variant":"cURL"},{"key":"php","label":"PHP","variant":"Guzzle"},{"key":"php","label":"PHP","variant":"HTTP_Request2"},{"key":"php","label":"PHP","variant":"pecl_http"},{"key":"powershell","label":"PowerShell","variant":"RestMethod"},{"key":"python","label":"Python","variant":"http.client"},{"key":"python","label":"Python","variant":"Requests"},{"key":"r","label":"R","variant":"httr"},{"key":"r","label":"R","variant":"RCurl"},{"key":"ruby","label":"Ruby","variant":"Net::HTTP"},{"key":"shell","label":"Shell","variant":"Httpie"},{"key":"shell","label":"Shell","variant":"wget"},{"key":"swift","label":"Swift","variant":"URLSession"}],"languageOptions":[{"label":"C# - HttpClient","value":"csharp - HttpClient - C#"},{"label":"C# - RestSharp","value":"csharp - RestSharp - C#"},{"label":"cURL - cURL","value":"curl - cURL - cURL"},{"label":"Dart - http","value":"dart - http - Dart"},{"label":"Go - Native","value":"go - Native - Go"},{"label":"HTTP - HTTP","value":"http - HTTP - HTTP"},{"label":"Java - OkHttp","value":"java - OkHttp - Java"},{"label":"Java - Unirest","value":"java - Unirest - Java"},{"label":"JavaScript - Fetch","value":"javascript - Fetch - JavaScript"},{"label":"JavaScript - jQuery","value":"javascript - jQuery - JavaScript"},{"label":"JavaScript - XHR","value":"javascript - XHR - JavaScript"},{"label":"C - libcurl","value":"c - libcurl - C"},{"label":"NodeJs - Axios","value":"nodejs - Axios - NodeJs"},{"label":"NodeJs - Native","value":"nodejs - Native - NodeJs"},{"label":"NodeJs - Request","value":"nodejs - Request - NodeJs"},{"label":"NodeJs - Unirest","value":"nodejs - Unirest - NodeJs"},{"label":"Objective-C - NSURLSession","value":"objective-c - NSURLSession - Objective-C"},{"label":"OCaml - Cohttp","value":"ocaml - Cohttp - OCaml"},{"label":"PHP - cURL","value":"php - cURL - PHP"},{"label":"PHP - Guzzle","value":"php - Guzzle - PHP"},{"label":"PHP - HTTP_Request2","value":"php - HTTP_Request2 - PHP"},{"label":"PHP - pecl_http","value":"php - pecl_http - PHP"},{"label":"PowerShell - RestMethod","value":"powershell - RestMethod - PowerShell"},{"label":"Python - http.client","value":"python - http.client - Python"},{"label":"Python - Requests","value":"python - Requests - Python"},{"label":"R - httr","value":"r - httr - R"},{"label":"R - RCurl","value":"r - RCurl - R"},{"label":"Ruby - Net::HTTP","value":"ruby - Net::HTTP - Ruby"},{"label":"Shell - Httpie","value":"shell - Httpie - Shell"},{"label":"Shell - wget","value":"shell - wget - Shell"},{"label":"Swift - URLSession","value":"swift - URLSession - Swift"}],"layoutOptions":[{"value":"classic-single-column","label":"Single Column"},{"value":"classic-double-column","label":"Double Column"}],"versionOptions":[],"environmentOptions":[{"value":"0","label":"No Environment"},{"label":"sandbox","value":"54606592-16996205-c16a-435d-a412-90cd7244d2f7"}],"canonicalUrl":"https://docs.cards.zvxlab.com/view/metadata/2sBXqNkJ6c"}