Sardine SDK Integration

Step-by-step guide for integrating Sardine's Device Intelligence & Behavior Biometrics SDK with Cybrid transfers and executions to enable enriched risk screening.

The Sardine Risk SDK Integration allows your application to collect device intelligence and behavioral biometrics from your end-users and correlate them with Cybrid's server-side transfer screening. This gives Sardine richer signals to assess transaction risk — including device fingerprinting, bot detection, and behavioral anomalies — beyond what is available from PII and transaction data alone.

The integration involves two independent channels that are linked by a shared session key:

  • Client side — Your application initializes the Sardine SDK, which collects device signals asynchronously and sends them directly to Sardine. The session key tags those signals to a specific user session.
  • Server side — When creating a transfer or execution, you pass the Sardine session GUID to the Cybrid API, which forwards the session key to Sardine during screening so it can match the device signals to the transaction.

Process Overview

  1. Prerequisites — Obtain Sardine access credentials and configure custom subdomains for the Sardine SDK.

  2. Step 1 — Install the Sardine SDK in your client application.

  3. Step 2 — Create a Sardine session by calling the Cybrid API. The response contains the sardine_client_id and sardine_session_key to pass to the SDK, and a guid to include in the transfer or execution request.

  4. Step 3 — Set up the SDK with the sardine_client_id, then update its configuration with the sardine_session_key to start collecting device signals. Await the SDK call before submitting a transfer or execution.

  5. Step 4 — Include the Sardine session guid in the transfer or execution request. The platform uses it to enable device-enriched risk screening.


Prerequisites

Before starting the integration, ensure the following are in place:

✅

Request your Sardine access credentials from Cybrid

Cybrid issues your Sardine access credentials once the Sardine integration is included in your signed agreement. Contact Cybrid to have them provisioned:

Custom subdomains — Sardine recommends routing SDK traffic through custom subdomains under your own domain. This has several benefits:

  • Increased Performance — Using a custom subdomain can result in a significant increase in accuracy in browsers with strict privacy features, such as Safari or Firefox. This is because the custom subdomain allows for the recognition of cookies as "first-party", which can extend the lifetime of device IDs and improve performance.
  • Ad-blocker Resistance — Ad-blockers will not block the JavaScript agent from sending identification requests to the server, as sending data to an internal URL (such as a subdomain) is allowed. This makes it less likely that the data being sent will be blocked.
  • Harder to Detect — Routing through a custom subdomain makes the fingerprinting process harder for automated blockers and fraudsters to detect, because requests sent directly to a separate third-party domain are easier to identify and block.
⚠️

Custom subdomains require DNS configuration

You must create two subdomains under your domain (for example, api.example.com and p.example.com) and configure CNAME records pointing to Sardine's infrastructure. See Sardine's Custom Subdomain Integration Guide for the full setup instructions, including CNAME records, CAA configuration, and certificate provisioning.


Step 1: Install the Sardine SDK

Add the Sardine NPM access token to your .npmrc file:

//registry.npmjs.org/:_authToken=${NPM_TOKEN}

Then install the appropriate package for your framework:

npm install @sardine-ai/web-sdk

For mobile applications, refer to Sardine's Mobile SDK documentation.


Step 2: Create a Sardine Session

Create a Sardine session by calling the Cybrid API when your application loads for a signed-in customer, or right after the customer signs in. Creating the session early lets the SDK collect device signals and behavior biometrics across the customer's whole flow, not only on the transfer screen.

The response returns:

  • sardine_client_id — the client ID to set up the Sardine SDK with (Step 3).
  • sardine_session_key — the UUID session key to pass to the Sardine SDK (Step 3).
  • guid — the Cybrid session identifier to include in your transfer or execution request (Step 4).

POST /api/sardine_sessions — Cybrid API docs

Required scope: sardine_sessions:execute

{
  "customer_guid": "customer_guid"
}
ℹ️

customer_guid is inferred for customer tokens

If your application uses a customer-scoped access token, customer_guid is derived from the token automatically and the field may be omitted.

Request Body Field Reference

FieldTypeRequiredDescription
customer_guidstringConditionalThe GUID of the customer the session is for. Required for organization and bank subject tokens. Inferred from the token for customer subject tokens.
{
  "guid": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
  "sardine_session_key": "550e8400-e29b-41d4-a716-446655440000",
  "sardine_client_id": "sardine_client_id",
  "customer_guid": "customer_guid",
  "expires_at": "2026-01-01T01:00:00.000Z"
}

Response Field Reference

FieldTypeDescription
guidstringThe Cybrid GUID for this session. Pass this as sardine_session_guid in the transfer or execution request (Step 4).
sardine_session_keystringThe UUID session key to pass to the Sardine SDK as sessionKey (Step 3).
sardine_client_idstringThe client ID to set up the Sardine SDK with, passed as clientId (Step 3).
customer_guidstringThe customer this session is associated with. Pass this to the Sardine SDK as customerId (Step 3).
expires_atdatetimeThe datetime when this session key expires. Store this value and refresh the session before it expires. See Session Key Lifecycle for guidance.
⚠️

Be mindful of expires_at

Check this value before submitting a transfer or execution and refresh the session if it is close to expiry. See Session Key Lifecycle for when and how to refresh.

ℹ️

Store session values for subsequent steps

Store the guid, sardine_session_key, sardine_client_id, and customer_guid in your application state for use in Steps 3 and 4.


Step 3: Set Up the SDK and Collect Device Signals

Set up the Sardine SDK with the sardine_client_id from Step 2, then update its configuration with the sardine_session_key and the Cybrid customer_guid. Setup only loads the SDK; Sardine starts collecting device signals on the first configuration update. Follow Sardine's recommendations on how to update the configuration throughout your user flows to ensure device signals are captured before the transfer or execution is submitted.

The flow value is a label you define to identify the stage of your application (for example, "transfer" or "checkout").

⚠️

Behavior Biometrics consent required

If you use Sardine's Behavior Biometrics feature, ensure that your End User agrees to your privacy policy before you begin collecting their Behavior Biometric data.

Call setupSardine once with the values from Step 2, then await the first updateSardineConfig call. If you configured custom subdomains in the Prerequisites, include them in the setup.

import { setupSardine, updateSardineConfig } from '@sardine-ai/web-sdk';

setupSardine({
  clientId: sardineClientId,         // sardine_client_id from Step 2
  environment: 'sandbox',            // or 'production'
  apiSubdomain: 'api.example.com',   // recommended — your configured API subdomain
  pixelSubdomain: 'p.example.com',   // recommended — your configured pixel subdomain
});

await updateSardineConfig({
  customerId: customerGuid,          // customer_guid from Step 2
  sessionKey: sardineSessionKey,     // sardine_session_key from Step 2
  flow: 'transfer',
});
ℹ️

Make the first configuration update a single call

Await the first updateSardineConfig / updateSardineConfigAsync call and do not run other updates concurrently with it. Later calls only need the keys that change — for example, a new flow as the customer moves through your application.

⚠️

Always await the SDK call before submitting the transfer or execution

If you call the Cybrid API before the SDK callback completes, Sardine will not find device data for that session and the request will be screened without device signals.

ℹ️

More SDK options

The examples above cover the web JS and React SDKs. Sardine provides SDKs for other platforms — see Sardine's Risk SDK overview for the full list. On every platform, set up the SDK with sardine_client_id and pass sardine_session_key as the session key.


Step 4: Submit a Transfer or Execution with the Sardine Session GUID

Include the sardine_session_guid field using the guid returned in Step 2 when creating a transfer or execution. The platform uses it to correlate the device signals collected by the Sardine SDK with the screening request.

⚠️

Ensure device signals have been sent to Sardine before calling this API

Complete Step 3 and await the SDK callback before submitting a transfer or execution. If you call this API before the SDK has finished sending signals, Sardine will not be able to match device data to the session and the request will be screened without device intelligence.

ℹ️

Backward compatible

If sardine_session_guid is omitted or null, the transfer or execution is screened using server-side data only. Existing integrations continue to work unchanged.

Transfers

POST /api/transfers — Cybrid API docs

Required scope: transfers:execute

The sardine_session_guid field is supported for funding and instant_funding transfer types.

{
  "quote_guid": "quote_guid",
  "transfer_type": "funding",
  "external_bank_account_guid": "external_bank_account_guid",
  "source_participants": [
    {
      "type": "customer",
      "guid": "customer_guid",
      "amount": 10000
    }
  ],
  "destination_participants": [
    {
      "type": "customer",
      "guid": "customer_guid",
      "amount": 10000
    }
  ],
  "sardine_session_guid": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
}
FieldTypeRequiredDescription
sardine_session_guidstringNoThe guid of the Sardine session created in Step 2. When provided, the platform uses device signals collected by the Sardine SDK to enrich transfer screening.

Executions

POST /api/executions — Cybrid API docs

Required scope: executions:execute

{
  "plan_guid": "plan_guid",
  "sardine_session_guid": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
}
FieldTypeRequiredDescription
sardine_session_guidstringNoThe guid of the Sardine session created in Step 2. When provided, the platform uses device signals collected by the Sardine SDK to enrich execution screening.

Session Key Lifecycle

Expiry

The expires_at field in the session creation response indicates when the session key expires.

When expires_at is set:

  • Check expires_at before submitting a transfer or execution. If the session has expired, create a new one and await updateSardineConfig / updateSardineConfigAsync with the new sessionKey before proceeding. You don't need to set up the SDK again unless the new session returns a different sardine_client_id (see Sardine Client ID Changes).
  • Refresh at least whenever the user's session is refreshed. A Sardine session should not outlive the user's authenticated session.

Reuse Across Transactions

You may reuse the same Sardine session key across multiple transfers within the same user session. Reusing the key allows Sardine to accumulate device signals across the session, which can improve risk assessment accuracy. There is no need to create a new session for each transfer as long as the session has not expired.

When to Create a New Session

Create a new Sardine session when:

  • The current session has expired (expires_at is in the past).
  • The user logs out and back in.
  • You receive an invalid_sardine_session or sardine_session_expired error on a transfer or execution (see API Errors below).

Sardine Client ID Changes

The sardine_client_id only changes if Cybrid rotates its Sardine credentials, which is rare. Because you set up the SDK after creating a session, a new client ID takes effect the next time your application loads for a signed-in customer.

⚠️

Set up the SDK again if the client ID changes

The Sardine SDK cannot change its client ID through updateSardineConfig / updateSardineConfigAsync. If a new session returns a sardine_client_id that differs from the one the SDK was set up with, set the SDK up again before collecting signals for the new session. Reloading the page is the simplest option.


API Errors

Session Creation Errors

HTTP StatusError CodeCauseResponse
422not_foundCustomer GUID not found or does not belong to the requesting principal"Invalid customer for this request"
422invalid_parameterUpstream session creation failed"Sardine session creation failed"

Transfer and Execution Errors

These errors are returned when POST /api/transfers or POST /api/executions includes a sardine_session_guid that is not found or has expired. When you receive either error, create a new Sardine session (Step 2), update the SDK with the new session key (Step 3), and resubmit the request with the new sardine_session_guid. Set up the SDK again only if the new session returns a different sardine_client_id (see Sardine Client ID Changes).

HTTP StatusError CodeCauseResponse
422invalid_sardine_sessionThe sardine_session_guid provided does not match any session"Sardine session is invalid"
422sardine_session_expiredThe session key has passed its expires_at time"Sardine session has expired"

For full API schema details, see the Create Sardine Session API reference.


Did this page help you?