# GMetri Webhooks

You can use Webhooks to get data from GMetri into your system/platform. Webhooks are supported for viewer's variable changes, session creations, and rule triggers.

GMetri Webhooks are pseudo real-time with a max delay of 60 seconds.

If there are a large number of responses, GMetri will batch responses in groups of 500, sent with a minimum gap of 200ms between consecutive queries.

GMetri doesn't have the ability to resend/retry webhooks incase of an error response.

## Webhook Response

<mark style="color:green;">`POST`</mark> `https://example.com/user/endpoint/gmetri-webhook`

This webhook sends back an array of responses (viewer updates, session creation). Responses could be one of three types - variables, rules, session. Viewers are identified by their `identifier`, which depends on the authentication mechanism selected for the deployment.

Two inputs are needed from you to enable this webhook:

1\) Webhook URL (POST API)

2\) Webhook Basic Auth String (Any cryptographically secure string, >16 characters recommended)

#### Headers

| Name                                            | Type | Description          |
| ----------------------------------------------- | ---- | -------------------- |
| Authorization<mark style="color:red;">\*</mark> |      | Basic \<credentials> |

#### Request Body

| Name                                   | Type   | Description                   |
| -------------------------------------- | ------ | ----------------------------- |
| type<mark style="color:red;">\*</mark> | String | variables \| rules \| session |
| data<mark style="color:red;">\*</mark> | JSON   | WebhookData (described below) |

{% tabs %}
{% tab title="200: OK Webhook expects a response code of 200" %}

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Webhook Body" %}

```typescript
type WebhookBody = {
  type: "variables" | "session" | "rules",
  data: { //WebhookData
    orgSlug: string,
    depSlug: string,    
    rows: (VariableWebhookData | SessionWebhookData | RuleWebhookData)[]
  }  
}
```

{% endtab %}

{% tab title="VariableWebhook" %}
{% code title="VariableWebhookData Type" %}

```typescript
type VariableWebhookData = {
  identifier: string,
  variables: Record<string, any>, //A map of variable name and value
};
```

{% endcode %}

Example Response with VariableWebhook:

{% code title="Response Body" %}

```javascript
{
  type: "variables",
  data: {
    orgSlug: "gmetri",
    depSlug: "gmetridemo",
    rows: [{
      identifier: "amit@gmetri.com",
      variables: {
        score: 100,
        quizCompleted: true,
      }
    }, {
      identifier: "mitul@gmetri.com",
      variables: {
        score: 75,
        quizCompleted: false,
      }
    }]
  }
}
```

{% endcode %}
{% endtab %}

{% tab title="RuleWebhook" %}
{% code title="RuleWebhookData Type" %}

```typescript
type RuleWebhookData = {
  identifier: string,
  rules: {
    cid: number, //rule id
    cname: string, //rule name
    scene_name: string, //scene name where the rule was triggered
    timestamp: number, // epoch ms
  }[]
};
```

{% endcode %}

Example Webhook Response with RuleWebhook:

{% code title="Response Body" %}

```javascript
{
  type: "rules",
  data: {
    orgSlug: "gmetri",
    depSlug: "gmetridemo",
    rows: [{
      identifier: "amit@gmetri.com",
      rules: [{
        cid: 1,
        cname: "Rule A",
        scene_name:  "scene 1",
        timestamp: 123456
      }]
    }, {
      identifier: "mitul@gmetri.com",
      rules: [{
        cid: 1,
        cname: "Rule A",
        scene_name:  "scene 2",
        timestamp: 123457
      }, {
        cid: 2,
        cname: "Rule C",
        scene_name:  "scene 2",
        timestamp: 123458
      }]
    }, {
      identifier: "amit@gmetri.com",
      rules: [{
        cid: 10,
        cname: "Rule G",
        scene_name:  "scene 4",
        timestamp: 234561
      }]
    }]
  }
}
```

{% endcode %}
{% endtab %}

{% tab title="SessionWebook" %}

{% code title="SessionWebhookData Type" %}

```typescript
type SessionWebhookData = {
  identifier: string,
  session: Record<string, any>,
};
```

{% endcode %}

Example Response with VariableWebhook:

{% code title="Response Body" %}

```javascript
{
  type: "session",
  data: {
    orgSlug: "gmetri",
    depSlug: "gmetridemo",
    rows: [{
      identifier: "amit@gmetri.com",
      session: {
        uuid: "12134-dffgs-2345-vfsd",
        browser: "CHROME",
        platform: "ANDROID,
        device_id: "123",
        created_at: 123455,
        modified_at: 123455,
      }
    }, {
      identifier: "mitul@gmetri.com",
      session: {
        uuid: "12134-dffgs-2345-vfsd",
        browser: "CHROME",
        platform: "ANDROID,
        device_id: "123",
        created_at: xyz,
        modified_at: xyz,
      }
    }, {
      identifier: "amit@gmetri.com",
      session: {
        uuid: "12134-3214-2345-vfsd",
        browser: "CHROME 1",
        platform: "IOS",
        device_id: "456",
        created_at: 123456,
        modified_at: 123456,
    }
  }]
}
```

{% endcode %}
{% endtab %}
{% endtabs %}


---

# 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.gmetri.com/metaverse/sdk/gmetri-webhooks.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.
