> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gr4vy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Sardine

> Connect to Sardine for AI-powered fraud prevention and risk assessment.

Sardine AI, founded in 2020 and headquartered in Miami, is an AI-powered risk platform that helps financial institutions, fintechs, and merchants prevent fraud and ensure compliance by analyzing user behavior, device intelligence, and transaction data in real time. Using techniques like behavior biometrics, the platform detects sophisticated scams, stops money laundering, and improves customer onboarding by unifying risk data across various sources and providing insights through APIs and machine learning features.

## Credentials

To configure a Sardine connection, you need to set the
following credentials. `Client ID` and `Client Secret` can can be found or generated in the [Sardine sandbox dashboard](https://dashboard.sandbox.sardine.ai)
by navigating to the Admin & Settings menu > Organizations & Users > API Credentials. To set up a webhook endpoint and generate a `Webhook Secret` you need to contact your Sardine Implementations Manager.

| Credential     | Description                                                                                                       |
| :------------- | :---------------------------------------------------------------------------------------------------------------- |
| Client ID      | Your unique Sardine account ID                                                                                    |
| Client Secret  | The password used to sign API requests                                                                            |
| Webhook Secret | The secret used to validate the authenticity, integrity and security of webhook requests originating from Sardine |

## Decision mapping

While the default Sardine Decision responses don't directly return values to be mapped to the Gr4vy `accept`/`reject`/`review` decision values, this result can be achieved by creating a specific workflow in Sardine, which returns a tag matching one of the Gr4vy decision values. You must set up the workflow on Sardine as follows:

<Steps>
  <Step title="Create Workflow">
    * Access the [Sardine dashboard](https://dashboard.sandbox.sardine.ai/)
    * Select `Workflows` from the menu in the sidebar
    * Click `New Workflow`
    * Enter `get-decision` as the name of the workflow
    * Select `Customer` as the Input Type
    * Click `Save block`
  </Step>

  <Step title="Checkpoint">
    Add a single `Checkpoint` block with 2 checkpoints: `CUSTOMER` and `PAYMENT`
  </Step>

  <Step title="Multipath Splitter">
    Connected to the preceding `Checkpoint` block, you should add a `Multipath Splitter`
    block with the name set to `decision`. This block should have 3 paths. Your non-default paths each require
    at least 1 condition (this likely consists of choosing various risk
    levels to be associated with the path. To see an example setup, load the
    example workflow shown below)
  </Step>

  <Step title="Paths">
    Attach a single `End block` to each of the three paths, each with specific
    `action`(s) set. See the tabs below for the `action` settings for each `End
            block`:

    <Card>
      <Tabs>
        <Tab title="End block 1">
          **Action:**

          | Property | Value      |
          | -------- | ---------- |
          | Action   | Update Tag |
          | Entity   | Session    |
          | Tag      | decision   |
          | Value    | `accept`   |
        </Tab>

        <Tab title="End block 2">
          **Action 1:**

          | Property | Value      |
          | -------- | ---------- |
          | Action   | Update Tag |
          | Entity   | Session    |
          | Tag      | decision   |
          | Value    | `review`   |

          **Action 2:**

          | Property   | Value                                            |
          | ---------- | ------------------------------------------------ |
          | Action     | Add to queue                                     |
          | Queue type | Session                                          |
          | Queue      | Choose the Alert queue you've set up for reviews |
        </Tab>

        <Tab title="End block 3">
          **Action:**

          | Property | Value      |
          | -------- | ---------- |
          | Action   | Update Tag |
          | Entity   | Session    |
          | Tag      | decision   |
          | Value    | `reject`   |
        </Tab>
      </Tabs>
    </Card>
  </Step>
</Steps>

<Warning>
  Please note that it is essential that the workflow is set up correctly. If the
  following conditions are not met, all attempted Sardine transaction risk
  requests return an `error` decision: \* The workflow must be named
  `get-decision` \* There must be 3 `End blocks`, with the following action
  Values: `accept`, `review`, `reject` and with the Action Tag set to `decision`

  * The `review` path must enqueue an Alert
</Warning>

### Example workflow

To load an example workflow following the structure laid out in the preceding section, take the following steps:

1. Access the [Sardine dashboard](https://dashboard.sandbox.sardine.ai/)
2. Select `Workflows` from the menu in the sidebar
3. Click `New Workflow`
4. Enter `get-decision` as the name of the workflow
5. Select `Customer` as the Input Type
6. Click `Save block`
7. Click the "three-dot" menu button beside your workflow name in the top right and select `Import Workflow`
8. Paste in the following JSON code:

```json Workflow code expandable wrap icon=code theme={"system"}
{
  "id": "get-decision",
  "name": "get-decision",
  "clientId": "",
  "inputType": "customer",
  "edges": [
    {
      "id": "6b34598c-8425-46da-8549-a5ffc0732225",
      "source": "root",
      "target": "6b34598c-8425-46da-8549-a5ffc0732225",
      "type": "buttonEdge",
      "markerEnd": {
        "type": "arrowclosed"
      },
      "data": {}
    },
    {
      "id": "d20c0028-9b19-4256-b601-3b23039867d9",
      "source": "6b34598c-8425-46da-8549-a5ffc0732225",
      "target": "d20c0028-9b19-4256-b601-3b23039867d9",
      "type": "buttonEdge",
      "markerEnd": {
        "type": "arrowclosed"
      },
      "data": {}
    },
    {
      "id": "ce2b8b65-7dfa-4003-b089-2511f210866f",
      "source": "d20c0028-9b19-4256-b601-3b23039867d9",
      "target": "ce2b8b65-7dfa-4003-b089-2511f210866f",
      "type": "buttonEdge",
      "markerEnd": {
        "type": "arrowclosed"
      },
      "data": {
        "path": "3fa72cb8-a7f4-4764-a41a-cee5425245fd"
      }
    },
    {
      "id": "5d30e5a6-27f9-460b-8c24-5a470060f3b0",
      "source": "d20c0028-9b19-4256-b601-3b23039867d9",
      "target": "5d30e5a6-27f9-460b-8c24-5a470060f3b0",
      "type": "buttonEdge",
      "markerEnd": {
        "type": "arrowclosed"
      },
      "data": {
        "path": "a7f8358a-9d5c-49ca-9258-112d7d8ad770"
      }
    },
    {
      "id": "517d7496-e691-4cb7-beef-67ec447ec2ce",
      "source": "d20c0028-9b19-4256-b601-3b23039867d9",
      "target": "517d7496-e691-4cb7-beef-67ec447ec2ce",
      "type": "buttonEdge",
      "markerEnd": {
        "type": "arrowclosed"
      },
      "data": {
        "path": "d534334c-9869-46be-b012-e99fb4c0a9a0"
      }
    }
  ],
  "nodes": [
    {
      "id": "root",
      "type": "start",
      "data": {
        "parentNodeId": "",
        "inputType": "customer",
        "nodeType": "start",
        "varReferences": null
      },
      "width": 96,
      "height": 52,
      "position": {
        "x": 0,
        "y": 0
      }
    },
    {
      "id": "6b34598c-8425-46da-8549-a5ffc0732225",
      "type": "checkpoint",
      "data": {
        "parentNodeId": "root",
        "nodeName": "Checkpoints",
        "checkpointNames": [],
        "checkpointIds": [5, 8],
        "nodeType": "checkpoint",
        "varReferences": null
      },
      "width": 231,
      "height": 76,
      "position": {
        "x": 0,
        "y": 0
      }
    },
    
    {
      "id": "ce2b8b65-7dfa-4003-b089-2511f210866f",
      "type": "end",
      "data": {
        "parentNodeId": "d20c0028-9b19-4256-b601-3b23039867d9",
        "nodeName": "Reject",
        "notes": "",
        "tags": [
          {
            "key": "decision",
            "value": "reject",
            "actionType": "update_tag"
          }
        ],
        "persistentTagActions": [],
        "queueActions": [],
        "listActions": [],
        "nodeType": "end",
        "varReferences": null,
        "color": "danger"
      },
      "width": 105,
      "height": 52,
      "position": {
        "x": 0,
        "y": 0
      }
    },
    {
      "id": "5d30e5a6-27f9-460b-8c24-5a470060f3b0",
      "type": "end",
      "data": {
        "parentNodeId": "d20c0028-9b19-4256-b601-3b23039867d9",
        "nodeName": "Review",
        "notes": "",
        "tags": [
          {
            "key": "decision",
            "value": "review",
            "actionType": "update_tag"
          }
        ],
        "persistentTagActions": [],
        "queueActions": [
          {
            "queueId": 708163,
            "reviewId": 0
          }
        ],
        "listActions": [],
        "nodeType": "end",
        "varReferences": null,
        "color": "warning"
      },
      "width": 111,
      "height": 52,
      "position": {
        "x": 0,
        "y": 0
      }
    },
    {
      "id": "517d7496-e691-4cb7-beef-67ec447ec2ce",
      "type": "end",
      "data": {
        "parentNodeId": "d20c0028-9b19-4256-b601-3b23039867d9",
        "nodeName": "Accept",
        "notes": "",
        "tags": [
          {
            "key": "decision",
            "value": "accept",
            "actionType": "update_tag"
          }
        ],
        "persistentTagActions": [],
        "queueActions": [],
        "listActions": [],
        "nodeType": "end",
        "varReferences": null,
        "color": "success"
      },
      "width": 111,
      "height": 52,
      "position": {
        "x": 0,
        "y": 0
      }
    }
  ]
}
```

9. Click `Submit`
10. Click `Confirm` when prompted about overriding the existing workflow
11. Click `Save` in the top right
12. In the pop-up prompt that confirms whether you want to save the workflow, switch on the toggle button labeled `Set as Live Version`
13. Click `Confirm` to save the workflow
14. You should now see the workflow listed on the workflows page, with the `Status` label set to `Live`

Please note, the conditions for each path in this example workflow should be modified to suit your needs. The example workflow has the `accept` path as the default path, and the Sardine risk levels associated with the `review`/`reject` paths are as follows:

| Sardine Risk Level  | Decision tag/Gr4vy Decision |
| ------------------- | --------------------------- |
| `medium`            | `review`                    |
| `high`, `very_high` | `reject`                    |

## Webhooks for manual review

To enable manual review you need to set up webhooks from your anti-fraud service to the system. This
webhook is used to notify the system when a review is accepted or rejected.

To get the webhook URL, head over to your connection by going to **Connections** ->
**\[Anti-Fraud connection]** -> **Synchronization** and copy the webhook URL.

To have webhooks enabled on Sardine, contact your assigned Implementation Manager from Sardine, with your Webhook URL and mention that you want to receive `Case` type webhooks. Once your webhooks have been enabled, Sardine sends you the `Webhook Secret`, which is used for webhook validation as mentioned in the preceding section.

<Warning>
  If you do not add the `Webhook Secret` to your dashboard, the webhook
  signature validation process is skipped, which may put your system at
  risk of attacks from tampered webhook payloads.
</Warning>

## Review queue clearing

If a transaction is marked for review, and subsequently it is voided from the Gr4vy dashboard, then a request is sent to Sardine to clear any pending Sardine Alerts for that transaction.

## Device fingerprinting

The use of device fingerprinting is highly recommended when using Sardine. Please refer to the
[device fingerprinting guide](/guides/features/anti-fraud/fingerprint) for more information on the universal solution.

If needed, you could load the [fingerprint script for Sardine][script] directly and pass the `sessionKey`
value as the `anti_fraud_fingerprint` to the [new transaction API](/reference/transactions/new-transaction).

Biometrics are enabled by default, which may result in the following console errors and warnings:

<AccordionGroup>
  <Accordion title="Errors" icon="circle-exclamation">
    <Danger>
      \[Violation] Permissions policy violation: accelerometer is not allowed in
      this document.
    </Danger>

    <Danger>
      \[Violation] Potential permissions policy violation: microphone is not
      allowed in this document.
    </Danger>

    <Danger>
      \[Violation] Potential permissions policy violation: camera is not allowed
      in this document.
    </Danger>
  </Accordion>

  <Accordion title="Warnings" icon="bell">
    <Warning>
      The `devicemotion` events are blocked by permissions policy. See
      [https://github.com/w3c/webappsec-permissions-policy/blob/master/features.md#sensor-features](https://github.com/w3c/webappsec-permissions-policy/blob/master/features.md#sensor-features)
    </Warning>

    <Warning>
      The `deviceorientation` events are blocked by permissions policy. See
      [https://github.com/w3c/webappsec-permissions-policy/blob/master/features.md#sensor-features](https://github.com/w3c/webappsec-permissions-policy/blob/master/features.md#sensor-features)
    </Warning>
  </Accordion>
</AccordionGroup>

[script]: https://docs.sardine.ai/guides/integration/riskSDK/webSDKs/javascript
