# Collect and Send Data

### Collect and Send Data

With the VGS Collect SDK, you can tokenize data via the **Vault API** or securely send it to your server using the **VGS Proxy**.

### Send Data to Your Server via VGS Proxy

Using the `submit(_:)` method, sensitive data from `VGSTextInput` will be collected, stored in your organization's Vault, and sent to the Upstream URL specified in the Inbound Route.

#### Send Data

Use `submit(:)` function to send secured data to your backend and store it in your organization's Vault.

```javascript
// - `path` (string, optional): The API endpoint path.
// - `method` (string, optional): The HTTP method (default is POST).
// - `extraData` (Record<string, any>, optional): Additional data to send.
// - `customRequestStructure` (Record<string, any>, optional): JSON pattern, applies a custom structure template to the collected sensitive data.
// - Returns a Promise that resolves with the server response, or rejects with a validation error./
submit(path: string = '', method: string = 'POST', extraData: Record<string, any> = {}, customRequestStructure?: Record<string, any>): Promise<{ status: number; response: any }>
```

#### Code example

```javascript
// Setup your vauldId and environment
const collector = new VGSCollect('vaultId', 'sandbox');

try {
    const { status, response } = await collector.submit('/post', 'POST');
    if (response.ok) {
    try {
        const responseBody = await response.json();
        const json = JSON.stringify(responseBody, null, 2);
        console.log('Success:', json);
    } catch (error) {
        console.warn(
        'Error parsing response body. Body can be empty or your <vaultId> is wrong!',
        error
        );
    }
    } else {
    console.warn(`Server responded with error: ${status}\n${response}`);
    if (status === 400) {
        console.error('Bad request! Check your VGSCollect config and input.');
    } else if (status === 500) {
        console.error('Server issue! Try again later.');
    }
    }
} catch (error) {
    if (error instanceof VGSError) {
    switch (error.code) {
        case VGSErrorCode.InputDataIsNotValid:
        for (const fieldName in error.details) {
            console.error(
            `Not valid fieldName: ${fieldName}: ${error.details[fieldName].join(', ')}`
            );
        }
        break;
        default:
        console.error('VGSError:', error.code, error.message);
    }
    } else {
    console.error('Network or unexpected error:', error);
    }
}
```

> • Data will be collected from all text fields that registered to current `VGSCollect`instance and send to your organization Vault.\
> • By default `aliases` are not a part of response data for `sendData(_:)` request. It's your responsibility to configure a response for the client after the data goes through the Inbound Proxy to your backend. However, if you test `sendData(_:)` request with our echo server, you will get a response with the same body as in the request, where the raw data will be redacted to aliases.

## Tokenize data

VGS offers two Vault API versions for data tokenization:\
• Vault API v1: Uses `tokenize(_:)`. [Learn more](/vault/developer-tools/apis/vault-api-v1.md).\
• Vault API v2: Uses `createAliases(_:)` and requires **Authorization**. [Learn more](/vault/developer-tools/apis/vault-api.md).\
\
Eeach API version requires appropriate *Upstream URL* specified in your Vault's Route configuration.\\

> • Vault API v2 is our newest Vault API and is recommended for integrations.\
> • If you already use API v1 you can find migration guide to API v2 below.\\

#### Tokenization API

Makes a tokenization request to Vault API v2 with data from \`VGSTextInputs\`:

{% code title="Vault API v2" %}

```typescript
public async createAliases(): Promise<{
  status: number;
  data: Record<string, string> | any;
}
```

{% endcode %}

Makes a tokenization request to Vault API v1 with data from \`VGSTextInputs\`:

{% code title="Vault API v1" %}

```typescript
public async tokenize(): Promise<{
  status: number;
  data: Record<string, string> | any;
}
```

{% endcode %}

#### Code example

Send a tokenization request with data from `VGSTextInputs`:

You should set accessToken into VGSCollect customHeaders before calling the createAliases(:) function:

{% code title="Vault API v2" %}

```javascript
collector.setCustomHeaders({ Authorization: 'Bearer <Access Token>' });
const { status, data } = await collector.createAliases();
```

{% endcode %}

{% code title="Vault API v1" %}

```javascript
const { status, data } = await collector.tokenize();
```

{% endcode %}

> * Data will be collected from all `VGSTextInputs` registered to current `VGSCollect`instance.\
>   \- Only data from `VGSTextInputs` configured with `tokenization` configurations will be tokenized and stored in your's organization vault.

### Tokenization Parameters

Each API version requires a tokenization configuration for each data type that you want to collect and tokenize.

To define **storage type** and **alias format,** you need to set up `TokenizationConfig` in `tokenize` field for each input that should collect data for tokenization.

#### Tokenization format

The tokenization format defines how the [alias](https://www.verygoodsecurity.com/docs/terminology/nomenclature/#alias-formats)) will appear in the response.\
Each field has a default format set by the SDK, but it can be overridden if needed.

| Field Type        | Default Format          |
| ----------------- | ----------------------- |
| `.cardNumber`     | `FPE_SIX_T_FOUR`        |
| `.cvc`            | `NUM_LENGTH_PRESERVING` |
| `.expDate`        | `UUID`                  |
| `.cardHolderName` | `UUID`                  |
| `.ssn`            | `UUID`                  |
| `.none`           | `UUID`                  |

#### Tokenization storage

VGS supports two storage types: `PERSISTENT` and `VOLATILE`.\
Available values are defined in the `VGSTokenizationConfiguration.storage` enum.

| Field Type        | Default Storage |
| ----------------- | --------------- |
| `.cardNumber`     | PERSISTENT      |
| `.cvc`            | VOLATILE        |
| `.expDate`        | PERSISTENT      |
| `.cardHolderName` | PERSISTENT      |
| `.ssn`            | PERSISTENT      |
| `.date`           | PERSISTENT      |
| `.none`           | PERSISTENT      |

> While most fields allow you to customize storage type, this setting cannot be changed for `.cvc` and `.cardNumber`.

#### Code example

```javascript
<VGSTextInput
    collector={collector}
    fieldName="expDate"
    type="expDate"
    /// setup default tokenization params
    tokenization={VGSTokenizationConfiguration.presets.expDate}
<VGSTextInput
    collector={collector}
    fieldName="card_holder"
    type="cardHolderName"
    /// setup custom tokenization params
    tokenization={{
        format: VGSTokenizationConfiguration.aliasFormat.UUID,
        storage: VGSTokenizationConfiguration.storage.PERSISTENT,
    }}
```

### Migrating from Vault API v1 to v2

Migration from Vault **API v1** to **API v2** will require you to implement the next steps:

* Update your organization's Vault Route with a new **Upstream Host**: use `https://<your-vault-id>.sandbox.vault-api.verygoodvault.com` for **sandbox** or `https://<your-vault-id>.live.vault-api.verygoodvault.com` for a **live** environment.
* Receive Tokenization **accessToken** from your backend and set it in **VGSCollect** headers:\
  `vgsCollect.setCustomHeaders(["Authorization": "Bearer (accessToken)"])`.
* Use `-createAliases(:)` function instead of `-tokenize(:)` to create aliases.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.verygoodsecurity.com/vault/developer-tools/vgs-collect/react-native-sdk/submit-data.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
