## Deprecated Deployment Method

This documentation covers the **legacy Request Manager Agent deployment** that supported ingress. This deployment method has been deprecated.

**New deployments should use the [simplified egress-only Request Manager Agent](https://docs.datagrail.io/docs/integrations/internal-systems-integrations/request-manager-agent/overview)**, which eliminates the need for public internet exposure.

Call an internal or third-party REST APIs to fulfill data subject access, deletion, opt-out, and identifier retrieval requests.

## Connection Configuration

The API Proxy connection uses the standard [Connection](https://docs.datagrail.io/docs/integrations/internal-systems-integrations/legacy-solutions/request-manager-agent-legacy/configuration/environment-variables#connection-schema) object schema to define the API contract using the APIProxy [ConnectorType](https://docs.datagrail.io/docs/integrations/internal-systems-integrations/legacy-solutions/request-manager-agent-legacy/configuration/environment-variables#connectortype). This ConnectorType requires an array of [APIProxyQuery](https://docs.datagrail.io/docs/integrations/internal-systems-integrations/legacy-solutions/request-manager-agent-legacy/configuration/connections/api-proxy/#apiproxyquery-schema) objects for its queries. Once the object has been created and the credentials have been stored, place the object in the [DataGrailAgentConfig](https://docs.datagrail.io/docs/integrations/internal-systems-integrations/legacy-solutions/request-manager-agent-legacy/configuration/environment-variables#datagrailagentconfig-schema)`connections` array.

### Example Connection Object

```json
{
  "name": "User Service",
  "uuid": "44d9e703-b8cf-40a8-a138-3cc110319b0d",
  "capabilities": ["privacy/access", "privacy/delete", "privacy/optout", "privacy/identifiers"],
  "mode": "live",
  "connector_type": "APIProxy",
  "queries": {
    "test": [
      {
        "url": "https://api.acme.com/v0/health-check",
        "headers": {
          "Authorization": "Basic {credentials}"
        },
        "verb": "GET",
        "verify_ssl": "true"
      }
    ],
    "identifiers": {
      "primary_phone_number": [
        {
          "url": "https://api.acme.com/v0/identifiers/get-phone?email={email}",
          "headers": {
            "Authorization": "Basic {credentials}",
            "Content-Type": "application/json"
          },
          "verb": "GET",
          "verify_ssl": "true",
          "valid_response_codes": [200]
        }
      ]
    },
    "access": [
      {
        "url": "https://api.acme.com/v0/users?email={email}",
        "headers": {
          "Authorization": "Basic {credentials}",
          "Content-Type": "application/json"
        },
        "verb": "GET",
        "verify_ssl": "true",
        "valid_response_codes": [200]
      }
    ],
    "delete": [
      {
        "url": "https://api.acme.com/v0/users",
        "headers": {
          "Authorization": "Basic {credentials}",
          "Content-Type": "application/json"
        },
        "body": "{{\"email\": \"{email}\" }}",
        "verb": "DELETE",
        "verify_ssl": "true",
        "valid_response_codes": [200, 404]
      }
    ],
    "optout": [
      {
        "url": "https://api.acme.com/v0/users/optout",
        "headers": {
          "Authorization": "Basic {credentials}",
          "Content-Type": "application/json"
        },
        "body": "{{\"email\": \"{email}\" }}",
        "verb": "PUT",
        "verify_ssl": "true",
        "valid_response_codes": [200, 201, 404]
      }
    ]
  },
  "credentials_location": "arn:aws:secretsmanager:Region:AccountId:secret:datagrail-apiproxy"
}
```

### Test Query Required

The API Proxy connector requires an additional `test` query (or queries) for health checks to determine that the API is available and healthy.

### APIProxyQuery Schema

| Field |  |
| --- | --- |
| url | **string** _(required)_<br> The full URL of the API endpoint. |
| headers | **object( [Headers](https://docs.datagrail.io/docs/integrations/internal-systems-integrations/legacy-solutions/request-manager-agent-legacy/configuration/connections/api-proxy/#headers))** _(optional)_<br> The headers to include in the API request. |
| body | **string** _(optional)_<br> The body to include in the API request. |
| verb | **string** _(required)_<br> The HTTP method for the API request. All HTTP methods are supported |
| verify_ssl | **string** _(required)_<br> Determines whether to verify the SSL certificate of the URL. Accepted values are `"true"` or `"false"`. |
| valid_response_codes[] | **integer** _(required for v0.10.0+)_<br> Status codes that the Agent should consider successful. The default value is `[200]`. <br>**Note:** An instance of a data subject not existing should be handled the same as a successful request. If the API returns 404, for example, 404 should be added to the array. |
| fail_retry_response_codes[] | **integer** _(required for v0.10.0+)_<br> Status codes that the Agent should consider unsuccessful and should be retried. |

### Headers

| Field |  |
| --- | --- |
| <header_name> | **string**<br> The value of the header. |

JSON Representation

```json
{
  "<header_name>": string
}
```

### Substitutions

The `url`, `headers`, and `body` parameters support named substitutions through string interpolation to format with identifiers coming from DataGrail, and values stored in your credentials manager. To make a substitution, enclose the variable name in curly braces in the string.

#### URL

```json
"url": "https://api.acme.com/v2/data-subject-request?email={email}"
```

#### Headers

```json
"headers": {
    "Authorization": "Basic {credentials}"
}
```

#### Body

```json
"body": "{{\"email\": \"{email}\" }}"
```

### API Contract

The APIProxy connection is designed to work with APIs that meet the following requirements:

### Authentication

The API must support static token-based authentication and that token must be stored in your credentials manager.

### Request/Response Flow

The API must support a synchronous response flow whereby all operations occur over a single open connection.

Each request must be stateless and perform deletion, identifier, or data retrieval without any context of previously executed queries.

### Request Timeout

All API requests for a given query type must be completed in under **5 minutes** by default.

### Response Body Format

#### Access Requests

The response body of an access request must be an array of objects. The value of each key can be of any datatype, including arrays and nested objects. Each object in the array will be converted into a separate file for your data subject.

#### Deletion Requests

The status code is the only signal used to determine if a deletion request was successful.

#### Test Requests

The status code is the only signal used to determine if the API is available and healthy.

#### Identifier Requests

The response body of an identifier retrieval request must be an array of objects. The key must be the `snake_case` name, and the value must be the identifier value.

### Need help?

If you have any questions, please reach out to your dedicated Account Manager or contact us at [support@datagrail.io](mailto:support@datagrail.io).

_Disclaimer: The information contained in this message does not constitute as legal advice. We would advise seeking professional counsel before acting on or interpreting any material._
