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

# Subscriber Resolving via an API and Target System (e.g., CRM or RADIUS Server)

## API Subscriber Resolver

By default, Guardian Ops assigns events to cases based on the **IP address** of the incoming event. This IP serves as the **Customer Identifier**.

The **Inbound Processing** workflow allows you to build a decision tree that uses event metadata to determine which subscriber (customer) is responsible for an event and assign an identifier accordingly.

AbuseHQ provides a set of **Resolvers** to extract and evaluate different pieces of metadata. One of the most powerful is the **API Resolver**.

## What Is the API Resolver?

The **API Resolver** allows you to pass information (such as the **IP address** and **event timestamp**) from an incoming event to your **RESTful API endpoint**.\
Your backend system (e.g., CRM or RADIUS) then returns the correct **Subscriber Identifier**.

### Common Use Case

Look up the subscriber assigned to an IP address at the time of an event using:

* `IP address`
* `Event timestamp`

## How to Configure an API Resolver

To configure an API Resolver in Guardian Ops:

1. Open the **Admin Portal**.
2. Click **Settings** in the left menu under **Guardian Ops**.
3. Click on **New API resolver** in the top right.
4. Fill in the **name** and **description**.
5. Provide the **API endpoint**, **authentication credentials**, and any **required parameters**.

> ⚠️ If your API is behind a firewall, ensure the following outgoing IPs are allowed:
> 18.193.183.51
> 52.57.46.129
> 18.158.191.233

***

## What Information Should an API Resolver Return?

The API Resolver expects a **JSON response** (recommended) with specific fields.

### ✅ Minimal Response

```json theme={null}
{ "id": "ABCDEFGH1234" }
```

#### Full Resolver JSON Example

```
{
  "subscriber": {
    "id": "<subscriber_id>",
    "resolver_data": {
      "<subscriber_key1>": "<subscriber_value1>",
      "<subscriber_key2>": "<subscriber_value2>"
    }
  },
  "contract": {
    "id": "<contract_id>",
    "resolver_data": {
      "<contract_key1>": "<contract_value1>",
      "<contract_key2>": "<contract_value2>"
    }
  },
  "result_valid_from": "YYYY-MM-DDTHH:mm:ssZ",
  "result_valid_until": "YYYY-MM-DDTHH:mm:ssZ"
}
```

Please consult with Abusix support on each field’s supported and recommended uses.

> *⚠️ For string fields in the above structures, we generally accept all characters. However, we recommend you restrict values to alphanumerics with simple punctuation (e.g., ‘-‘, ” , ‘@’ etc.), and otherwise avoid characters that require URL encoding or are unsafe for use in URLs. Avoid using dots (‘.’); those will automatically be replaced with underscores (”)*

### **Subscriber**

The subscriber object must contain the globally unique **subscriber ID** and can optionally contain arbitrary key-value pairs of additional information on that subscriber.

**Guardian Ops** aggregates this information into a subscriber model that provides the latest values for each key and into the **resolver\_data field** of a case that contains a list of all seen values for each case.

 

### **Contract**

The contract object must contain the globally unique **contract ID** and can optionally contain arbitrary key-value pairs of additional information on that contract.

**Guardian Ops** aggregates these values into a contract model linked to a series of cases and always contains the latest values for each key.

 

### **HTTP Headers and Status Code**

**Guardian Ops** supports several response formats, including **JSON** and **XML**. The recommended response format is **JSON**.

**Guardian Ops** will send a **JSON** request

> `Accept: application/json`

header in its request\
\
and expects a \*\*JSON \*\*response

**JSON** Response

> `Content-Type: application/json`

header in the response.

### Status codes

**Guardian Ops** will interpret HTTP Status codes as follows:

* \*\*200 OK: \*\*Request completed successfully, and Customer Identification was provided
* \*\*404 Not Found: \*\*Request completed successfully, but no customer was found

Any other HTTP status code will be interpreted as a **temporary** **error**.

**Guardian Ops** will **queue** and retry the request several times within the time period you set..

We strongly recommend using the **timestamp**/**date** in your r**esolver config attributes** because there is no guarantee that events always come in “*real-time.*”

Some reporters send their reports with a delay; sometimes, queues can build up in **Guardian Ops**. We strongly recommend giving a caching timespan as big as your system allows it to be.

### Example

An event comes in and includes the [IP](https://abusix.com/glossary/internet-protocol-address/) 10.0.0.2 and the timestamp 2020-11-29T08:00:00Z:

> **\_⚠️ (The time this event arrives at AbuseHQ doesn’t matter! Let’s say it’s 2020-11-29T22:00:00Z) \_**

Both the [IP](https://abusix.com/glossary/internet-protocol-address/) and the timestamp are sent to the resolver.

The resolver responds with:

> ```
> {
>   "subscriber": {
>     "id": 111111,
>     "resolver_data": {
>       [...]
>     }
>   },
>   "contract": {
>     [...]
>   },
>   "result_valid_from": "2020-11-29T02:00:00Z",
>   "result_valid_until": "2020-11-29T12:00:00Z"
> }
> ```

 

NOTE:

> ```
> "result_valid_from": "[YYYY]-[MM]-[DD]T[hh]:[mm]:[ss]Z",
> "result_valid_until": "[YYYY]-[MM]-[DD]T[hh]:[mm]:[ss]Z"
> ```

 

This result is added to the cache, and every following event with the same [IP](https://abusix.com/glossary/internet-protocol-address/) and **timestamp** between **02:00** and **12:00** on **11-29** will not be queried again!
