{"templateId":"markdown","versions":[{"version":"1.0","label":"1.0","link":"/omni-api/1.0/overview/mtls-access","default":false,"active":false,"folderId":"6bec560c"},{"version":"1.1","label":"1.1","link":"/omni-api/1.1/overview/mtls-access","default":false,"active":false,"folderId":"6bec560c"},{"version":"1.2","label":"1.2","link":"/omni-api/overview/mtls-access","default":true,"active":true,"folderId":"6bec560c"}],"sharedDataIds":{"sidebar":"sidebar-omni-api/@1.0/overview/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["tabs","tab"]},"type":"markdown"},"seo":{"title":"Trusted Server Connection"},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"trusted-server-connection","__idx":0},"children":["Trusted Server Connection"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Choose the server-to-server connection option that fits your environment. Mutual TLS (mTLS) is designed for issuers that cannot use stable public egress addresses for source-IP allowlisting."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"connection-options","__idx":1},"children":["Connection options"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For each environment, choose one network-access path:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Source-IP allowlist:"]}," connect to the standard API hostname from approved public egress IP addresses or CIDR ranges."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["mTLS:"]}," connect to the dedicated mTLS hostname and present an issuer client certificate during the TLS handshake."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["These are separate connection paths. An mTLS request is not made to the source-IP-allowlisted hostname, and a client certificate is not sent to that hostname. In both cases, the same Omni endpoints, request bodies, and entity API token apply."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"choose-the-correct-base-url","__idx":2},"children":["Choose the correct base URL"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the base URL that matches both the environment and the network-access path you selected."]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Environment"},"children":["Environment"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Source-IP allowlist URL"},"children":["Source-IP allowlist URL"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"mTLS URL"},"children":["mTLS URL"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Sandbox"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://sandbox.percents.com"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://mtls.test.percents.com"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Production"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://prod.percents.com"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://mtls.prod.percents.com"]}]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The mTLS host uses the standard HTTPS port (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["443"]},"). Do not replace only part of a URL or route mTLS traffic through the standard host: select the complete base URL from this table."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"how-server-to-server-mtls-works","__idx":3},"children":["How server-to-server mTLS works"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Ordinary HTTPS verifies the Percents server to your client. With mTLS, your client also presents a certificate during the TLS handshake. Percents verifies that certificate before the API request is processed. This provides a second, cryptographic proof that the calling server holds the corresponding private key."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The mTLS certificate is a network-access credential, not an API authorization credential. Continue to send your entity-owned API token with every request:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"http","header":{"controls":{"copy":{}}},"source":"Authorization: token <token-id>:<token-secret>\n","lang":"http"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The client certificate and API token must both belong to the same entity. Percents then resolves that entity's issuer association and checks the issuer's API permissions. A valid certificate does not replace an API token or grant additional issuer access."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For background on the protocol and deployment model, see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://www.rfc-editor.org/rfc/rfc8446"},"children":["RFC 8446, the TLS 1.3 specification"]}," and the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://cheatsheetseries.owasp.org/cheatsheets/Transport_Layer_Security_Cheat_Sheet.html"},"children":["OWASP Transport Layer Security Cheat Sheet"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"quickstart","__idx":4},"children":["Quickstart"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"1-generate-a-private-key-and-csr","__idx":5},"children":["1. Generate a private key and CSR"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Generate the keypair in your own controlled environment. The private key must remain there: Percents never receives or returns a private key. A certificate signing request (CSR) contains the public key and certificate-subject information needed to issue a certificate; it is not a private key. Attach the CSR file to your request through the agreed secure channel."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This OpenSSL command generates a 2048-bit RSA private key and a CSR. Replace the example common name with an identifier meaningful to your integration team."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"umask 077\n\nopenssl req -new -newkey rsa:2048 -nodes \\\n  -keyout percents-omni-client.key \\\n  -out percents-omni-client.csr \\\n  -subj '/CN=issuer-omni-client'\n\nchmod 600 percents-omni-client.key\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Keep these files as follows:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["percents-omni-client.key"]}," — Keep private in your key-management system. It proves your client controls the certificate; Percents never receives or returns it."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["percents-omni-client.csr"]}," — Attach it to the request sent through the agreed secure channel. It requests a client certificate and contains the public key and subject information, not a private key."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["percents-omni-client.crt"]}," — Keep it with the private key after Percents returns it through the agreed secure channel. It is the signed public client certificate your HTTP client presents, not a private key."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"2-send-the-request-to-percents","__idx":6},"children":["2. Send the request to Percents"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Send the following to your assigned Percents account manager for ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["each environment"]}," you want to enable:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["issuer and program name;"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["environment: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sandbox"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["production"]},";"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["attach the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["percents-omni-client.csr"]}," file through the agreed secure channel;"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["the name and contact details of the technical owner; and"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["a change-request or support-ticket reference, if your organization uses one."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Do not include the private key, API token, webhook signing token, or live cardholder data. The CSR is appropriate to attach through the agreed secure channel because it is not a private key; use that approved transfer path for the signed certificate as well."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Percents returns the signed PEM client certificate through the agreed secure channel after the request is approved. Percents separately confirms when the certificate is active and ready for connection testing. Do not expect mTLS requests to succeed until you receive that readiness confirmation. Percents never returns a private key. Save the certificate as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["percents-omni-client.crt"]}," beside the private key in your approved secret or key-management system. Percents also confirms the applicable mTLS base URL from the table above. Your existing sandbox and production API tokens remain separate and continue to be required."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"3-inspect-the-returned-certificate","__idx":7},"children":["3. Inspect the returned certificate"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Before deployment, confirm the returned certificate is readable and that its public key matches the private key you generated:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"openssl x509 -in percents-omni-client.crt -noout -subject -issuer -dates\n\nopenssl x509 -in percents-omni-client.crt -pubkey -noout | openssl sha256\nopenssl pkey -in percents-omni-client.key -pubout | openssl sha256\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The two SHA-256 values from the final two commands must match. If they do not, stop and contact your account manager; do not deploy the certificate."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"4-make-a-sandbox-request","__idx":8},"children":["4. Make a sandbox request"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the sandbox mTLS URL, your client certificate, your private key, and the sandbox API token:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"export PERCENTS_API_BASE='https://mtls.test.percents.com'\nexport PERCENTS_API_TOKEN='tok_your_id:api_your_secret'\n\ncurl --fail-with-body \\\n  --cert percents-omni-client.crt \\\n  --key percents-omni-client.key \\\n  --header \"Authorization: token ${PERCENTS_API_TOKEN}\" \\\n  \"${PERCENTS_API_BASE}/api/v1/omni/merchant\"\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["After the sandbox request succeeds, use the separate production certificate, private key, API token, and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://mtls.prod.percents.com"]}," base URL for production. Do not reuse sandbox credentials in production."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"application-examples","__idx":9},"children":["Application examples"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Each example makes the same authenticated Omni request over mTLS. Replace the placeholders with values managed by your deployment environment; do not hard-code credentials or certificate paths in application source."]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Node.js","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"import fs from 'node:fs';\nimport https from 'node:https';\n\nconst options = {\n  hostname: 'mtls.test.percents.com',\n  path: '/api/v1/omni/merchant',\n  method: 'GET',\n  cert: fs.readFileSync(process.env.PERCENTS_MTLS_CERT_PATH),\n  key: fs.readFileSync(process.env.PERCENTS_MTLS_KEY_PATH),\n  headers: { Authorization: `token ${process.env.PERCENTS_API_TOKEN}` },\n};\n\nconst response = await new Promise((resolve, reject) => {\n  const request = https.request(options, (result) => {\n    let body = '';\n    result.setEncoding('utf8');\n    result.on('data', (chunk) => { body += chunk; });\n    result.on('end', () => resolve({ status: result.statusCode, body }));\n  });\n\n  request.on('error', reject);\n  request.end();\n});\n\nif (response.status < 200 || response.status >= 300) {\n  throw new Error(`Percents request failed: ${response.status}`);\n}\n\nconst merchants = JSON.parse(response.body);\n","lang":"javascript"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Python","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"import os\nimport requests\n\nresponse = requests.get(\n    \"https://mtls.test.percents.com/api/v1/omni/merchant\",\n    headers={\"Authorization\": f\"token {os.environ['PERCENTS_API_TOKEN']}\"},\n    cert=(\n        os.environ[\"PERCENTS_MTLS_CERT_PATH\"],\n        os.environ[\"PERCENTS_MTLS_KEY_PATH\"],\n    ),\n    timeout=30,\n)\nresponse.raise_for_status()\nmerchants = response.json()\n","lang":"python"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Java","disable":false},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Java's standard HTTP client can read a PKCS#12 keystore. Create one locally from the certificate and private key, then store both the keystore and its password through your approved key-management process:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"openssl pkcs12 -export \\\n  -in percents-omni-client.crt \\\n  -inkey percents-omni-client.key \\\n  -name percents-omni \\\n  -out percents-omni-client.p12\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"java","header":{"controls":{"copy":{}}},"source":"import java.io.FileInputStream;\nimport java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\nimport java.security.KeyStore;\nimport javax.net.ssl.KeyManagerFactory;\nimport javax.net.ssl.SSLContext;\n\nchar[] keyStorePassword = System.getenv(\"PERCENTS_MTLS_KEYSTORE_PASSWORD\").toCharArray();\nKeyStore keyStore = KeyStore.getInstance(\"PKCS12\");\ntry (FileInputStream input = new FileInputStream(System.getenv(\"PERCENTS_MTLS_KEYSTORE_PATH\"))) {\n  keyStore.load(input, keyStorePassword);\n}\n\nKeyManagerFactory keyManagers = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());\nkeyManagers.init(keyStore, keyStorePassword);\n\nSSLContext sslContext = SSLContext.getInstance(\"TLS\");\nsslContext.init(keyManagers.getKeyManagers(), null, null);\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(\"https://mtls.test.percents.com/api/v1/omni/merchant\"))\n    .header(\"Authorization\", \"token \" + System.getenv(\"PERCENTS_API_TOKEN\"))\n    .GET()\n    .build();\n\nHttpResponse<String> response = HttpClient.newBuilder()\n    .sslContext(sslContext)\n    .build()\n    .send(request, HttpResponse.BodyHandlers.ofString());\n\nif (response.statusCode() < 200 || response.statusCode() >= 300) {\n  throw new IllegalStateException(\"Percents request failed: \" + response.statusCode());\n}\n","lang":"java"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Go","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"package main\n\nimport (\n    \"crypto/tls\"\n    \"fmt\"\n    \"net/http\"\n    \"os\"\n)\n\nfunc main() {\n    certificate, err := tls.LoadX509KeyPair(\n        os.Getenv(\"PERCENTS_MTLS_CERT_PATH\"),\n        os.Getenv(\"PERCENTS_MTLS_KEY_PATH\"),\n    )\n    if err != nil {\n        panic(err)\n    }\n\n    client := &http.Client{Transport: &http.Transport{\n        TLSClientConfig: &tls.Config{Certificates: []tls.Certificate{certificate}},\n    }}\n\n    request, err := http.NewRequest(\n        http.MethodGet,\n        \"https://mtls.test.percents.com/api/v1/omni/merchant\",\n        nil,\n    )\n    if err != nil {\n        panic(err)\n    }\n    request.Header.Set(\"Authorization\", \"token \"+os.Getenv(\"PERCENTS_API_TOKEN\"))\n\n    response, err := client.Do(request)\n    if err != nil {\n        panic(err)\n    }\n    defer response.Body.Close()\n\n    if response.StatusCode < http.StatusOK || response.StatusCode >= http.StatusMultipleChoices {\n        panic(fmt.Sprintf(\"Percents request failed: %s\", response.Status))\n    }\n}\n","lang":"go"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"troubleshooting","__idx":10},"children":["Troubleshooting"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"What you see"},"children":["What you see"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Likely cause and next action"},"children":["Likely cause and next action"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["TLS handshake fails before an HTTP response"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The client certificate was not presented, is expired or revoked, is not trusted for this connection, or does not match the private key. Confirm the certificate/key pair and contact Percents if the issue persists."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["401 Unauthorized"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The API token is missing, malformed, or invalid. Verify the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Authorization: token ..."]}," header and the environment-specific token."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["403 Forbidden"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The certificate and API token do not represent the same entity, the certificate is no longer active, or the requested API capability is not enabled. Contact Percents with the timestamp and any response request identifier."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A request works on the standard host but not the mTLS host"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Confirm that you are using the mTLS URL for the correct environment and that the HTTP client is configured to present the certificate and private key."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Never send private keys, API tokens, or webhook signing tokens in an error report. Share the environment, timestamp, requested path, certificate subject or fingerprint, and any response request identifier with your account manager instead."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"rotate-or-revoke-a-certificate","__idx":11},"children":["Rotate or revoke a certificate"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Rotate before certificate expiry and after any relevant key-management policy change. Generate a ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["new"]}," keypair and CSR for every rotation; do not reuse the existing private key. Send the new CSR and identify the certificate being replaced to your account manager. After Percents confirms the new certificate is ready, deploy it and verify a request before retiring the old keypair from your systems."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If a private key may be compromised, or an integration is being decommissioned, contact your account manager immediately and request revocation. Include the environment and certificate subject or fingerprint, but never include the private key. Treat a revoked certificate as unusable and deploy a replacement before resuming mTLS traffic."]}]},"headings":[{"value":"Trusted Server Connection","id":"trusted-server-connection","depth":1},{"value":"Connection options","id":"connection-options","depth":2},{"value":"Choose the correct base URL","id":"choose-the-correct-base-url","depth":2},{"value":"How server-to-server mTLS works","id":"how-server-to-server-mtls-works","depth":2},{"value":"Quickstart","id":"quickstart","depth":2},{"value":"1. Generate a private key and CSR","id":"1-generate-a-private-key-and-csr","depth":3},{"value":"2. Send the request to Percents","id":"2-send-the-request-to-percents","depth":3},{"value":"3. Inspect the returned certificate","id":"3-inspect-the-returned-certificate","depth":3},{"value":"4. Make a sandbox request","id":"4-make-a-sandbox-request","depth":3},{"value":"Application examples","id":"application-examples","depth":2},{"value":"Troubleshooting","id":"troubleshooting","depth":2},{"value":"Rotate or revoke a certificate","id":"rotate-or-revoke-a-certificate","depth":2}],"frontmatter":{"seo":{"title":"Trusted Server Connection"}},"lastModified":"2026-10-02T20:53:32.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/omni-api/overview/mtls-access","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}