# Connecting a Bot via API

> Graspil offers different methods to connect a bot to the system. This article describes the method of connecting using the API. In your personal account, when connecting a bot, you can review all the connection options.

There are two methods for sending data to Graspil via the API:

1. [Batch Data Sending](#batch-data-sending) — the preferred method
2. [Real-Time Data Sending](#real-time-data-sending)

{% hint style="info" %}
In this article, "data" refers to a set of Update[^1] objects.
{% endhint %}

Graspil needs to receive the exact time when your bot (code) received the Update, accurate to milliseconds. Therefore, we recommend using the batch data sending method:

* You can provide the exact time of data receipt.
* If you delay data transmission, for example, sending it once a minute, it will positively affect the performance of all systems.

<details>

<summary><strong>Why is the Receipt Date Important, and When are Milliseconds Crucial?</strong></summary>

The receipt date of an Update object is necessary because not all Update data types contain a date.

**Why milliseconds?**&#x20;

Milliseconds are crucial if you also send outgoing traffic to Graspil. The system needs to properly sort the list of incoming and outgoing messages, and the only way to do this is by using the date. Often, receiving and sending messages occur within the same second, so we use milliseconds.

</details>

### Authorization

Graspil API expects the API key to be included in all API requests in the header, formatted as follows:

<table><thead><tr><th width="376">Name</th><th>Value</th></tr></thead><tbody><tr><td><code>Api-Key</code></td><td><code>meowmeowmeow</code></td></tr></tbody></table>

For more details on authorization and how to obtain the authorization key, see the [authorization section](#authorization).

### Verifying the Update Structure

In both methods, the system expects to receive Updates[^1] that fully comply with the Telegram Bot API structure. To speed up the process, the system checks only the basic parts of the data upon receipt. Full verification, including compliance with the Telegram Bot API structure, occurs later. If errors occur, they will be listed in the "[Bot Errors](https://app.graspil.com/bot_errors)" section.

{% hint style="info" %}
If you decide to collect updates manually, make sure that the data structure 100% matches the Telegram Bot API. Also, ensure that you send all the required data to Graspil; otherwise, it may distort the reports.

Examples of update structures can be found in the documentation: <https://core.telegram.org/bots/webhooks#testing-your-bot-with-updates>
{% endhint %}

### Batch Data Sending

**POST** `https://api.graspil.com/v1/send-batch-update`

This method is for batch sending Updates. You can send up to 1,000 updates with the receipt date specified. To send data, you need to send an array of data.

**Headers**

<table><thead><tr><th width="376">Name</th><th>Value</th></tr></thead><tbody><tr><td>Content-Type</td><td><code>application/json</code></td></tr><tr><td>Api-Key</td><td><code>meowmeowmeow</code></td></tr></tbody></table>

**Body**

<table><thead><tr><th width="128">Parameter</th><th width="123">Type</th><th width="147">Required</th><th>Описание</th></tr></thead><tbody><tr><td>date</td><td>RFC 3339 (<a href="https://en.wikipedia.org/wiki/ISO_8601">ISO 8601</a>)</td><td>No</td><td>The time the bot received a specific update. If not provided, the current time will be set. The time format must include milliseconds and the time zone. Example: <code>2024-08-03T20:00:00.123+02:00</code></td></tr><tr><td>update</td><td>Object <a href="https://core.telegram.org/bots/api#update">Update</a></td><td>Yes</td><td>A single <a href="https://core.telegram.org/bots/api#update">Update</a> object, the data you received from Telegram</td></tr></tbody></table>

{% hint style="danger" %}
The method accepts up to 1,000 Updates per request.
{% endhint %}

<details>

<summary>Example request body</summary>

{% code overflow="wrap" lineNumbers="true" %}

```json
[
    {
        "date": "2024-08-03T20:00:00.123+02:00", // date and time of data receipt
        "update": {
            "message": {
                "chat": {
                    "id": 123,
                    "type": "private",
                    "username": "Graspil",
                    "last_name": "Graspil",
                    "first_name": "Bot"
                },
                "date": 1718691840,
                "from": {
                    "id": 123,
                    "is_bot": false,
                    "username": "Graspil",
                    "last_name": "Graspil",
                    "first_name": "Bot"
                },
                "text": "Hi, how are you?",
                "message_id": 1000
            },
            "update_id": 22111111
        }
    },
    {
        "update": {
            "message": {
                "chat": {
                    "id": 123,
                    "type": "private",
                    "username": "Graspil",
                    "last_name": "Graspil",
                    "first_name": "Bot"
                },
                "date": 1718691840,
                "from": {
                    "id": 123,
                    "is_bot": false,
                    "username": "Graspil",
                    "last_name": "Graspil",
                    "first_name": "Bot"
                },
                "text": "Hi, how are you?",
                "message_id": 1000
            },
            "update_id": 22111112
        }
    }
]
```

{% endcode %}

</details>

#### Code examples

<details>

<summary>Python</summary>

{% code overflow="wrap" lineNumbers="true" %}

```python
import requests
import json

url = "https://api.graspil.com/v1/send-batch-update"
api_key = "< API KEY >"

payload = json.dumps([
  {
    "date": "2024-08-03T20:00:00.123+02:00",
    "update": {
        "message": {
            "chat": {
                "id": 123,
                "type": "private",
                "username": "Graspil",
                "last_name": "Graspil",
                "first_name": "Bot"
            },
            "date": 1718691840,
            "from": {
                "id": 123,
                "is_bot": false,
                "username": "Graspil",
                "last_name": "Graspil",
                "first_name": "Bot"
            },
            "text": "Hi, how are you?",
            "message_id": 1000
        },
        "update_id": 22111112
    }
  }
])
headers = {
  'Content-Type': 'application/json',
  'Api-Key': api_key,
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)

```

{% endcode %}

</details>

<details>

<summary>JS</summary>

{% code overflow="wrap" lineNumbers="true" %}

```javascript
var request = require('request');
var api_key = '< API KEY >'
var options = {
  'method': 'POST',
  'url': 'https://api.graspil.com/v1/send-batch-update',
  'headers': {
    'Content-Type': 'application/json',
    'Api-Key': api_key,
  },
  body: JSON.stringify([
    {
      "date": "2024-08-03T20:00:00.123+02:00",
      "update": {
        "message": {
          "chat": {
            "id": 123,
            "type": "private",
            "username": "Graspil",
            "last_name": "Graspil",
            "first_name": "Bot"
          },
          "date": 1718691840,
          "from": {
            "id": 123,
            "is_bot": false,
            "username": "Graspil",
            "last_name": "Graspil",
            "first_name": "Bot"
          },
          "text": "Hi, how are you?",
          "message_id": 1000
        },
        "update_id": 22111111
      }
    }
  ])

};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});

```

{% endcode %}

</details>

<details>

<summary>PHP</summary>

{% code overflow="wrap" lineNumbers="true" %}

```php
$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => 'https://api.graspil.com/v1/send-batch-update',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS =>'[
    {
        "date": "2024-08-03T20:00:00.123+02:00",
        "update": {
            "message": {
                "chat": {
                    "id": 123,
                    "type": "private",
                    "username": "Graspil",
                    "last_name": "Graspil",
                    "first_name": "Bot"
                },
                "date": 1718691840,
                "from": {
                    "id": 123,
                    "is_bot": false,
                    "username": "Graspil",
                    "last_name": "Graspil",
                    "first_name": "Bot"
                },
                "text": "Hi, how are you?",
                "message_id": 1000
            },
            "update_id": 22111112
        }
    }
]',
  CURLOPT_HTTPHEADER => [
    'Content-Type: application/json',
    'Api-Key: ' . $api_key
  ],
]);

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

{% endcode %}

</details>

**Response**

{% tabs %}
{% tab title="200" %}
{% code overflow="wrap" lineNumbers="true" %}

```json
{
  "ok": true
}
```

{% endcode %}
{% endtab %}

{% tab title="400" %}
{% code overflow="wrap" lineNumbers="true" %}

```json
{
  "ok": false,
  "error_code": 400,
  "description": "Too many updates. Max 1000"
}
```

{% endcode %}
{% endtab %}

{% tab title="401" %}
{% code overflow="wrap" lineNumbers="true" %}

```json
{
  "ok": false,
  "error_code": 401,
  "description": "Unauthorized"
}
```

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

### Real-Time Data Sending

**POST** `https://api.graspil.com/v1/send-update`

When you receive data from the Telegram Bot API, you need to send this data to our platform. The data should be sent in its original form, matching the Telegram Bot API data structure.

{% hint style="info" %}
For the system to work correctly, it is important to transmit data at the time of receipt, or use the [send-batch-update](#batch-data-sending) method with the receipt date if you are sending data later.
{% endhint %}

The data received from Telegram can contain two different structures, depending on the update delivery method: webhook or getUpdates. This method supports both structures.

**Headers**

| Name         | Value              |
| ------------ | ------------------ |
| Content-Type | `application/json` |
| Api-Key      | `meowmeowmeow`     |

**Body**

<details>

<summary>Example of the request body (webhook bot type)</summary>

{% code overflow="wrap" lineNumbers="true" %}

```json
{
  "update_id": 123,
  "message":{
    "date": 1691489960,
    "chat":{...}, // abbreviation, contains the Chat object from the TG API
    "message_id": 123,
    "from":{...}, // abbreviation, contains the User object from the TG API
    "text":"/start"
  }
}
```

{% endcode %}

</details>

<details>

<summary>Example of the request body (bot type getUpdates)</summary>

{% code overflow="wrap" lineNumbers="true" %}

```json
{
  "ok":true,
  "result":[
    {
      "update_id": 123,
      "message":{...} // abbreviation, contains the Message object from TG AP
    },
    {
      "update_id": 124,
      "message":{...} // abbreviation, contains the Message object from TG AP
    }
  ]
}
```

{% endcode %}

</details>

#### Code examples

<details>

<summary>Python</summary>

{% code overflow="wrap" lineNumbers="true" %}

```python
import requests

url = "https://api.graspil.com/v1/send-update"
api_key = ""  # your API key
data = {}  # received data from telegram

headers = {
    "Api-Key": api_key,
    "Content-Type": "application/json"
}

response = requests.post(url, json=data, headers=headers)

# Response processing
print(response.text)
```

{% endcode %}

</details>

<details>

<summary>PHP</summary>

{% code overflow="wrap" lineNumbers="true" %}

```php
$url = "https://api.graspil.com/v1/send-update";
$api_key = ""; // your API key
//$data - received data from telegram for sending

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Api-Key: ' . $api_key,
    'Content-Type: application/json;'
)];
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

$response = curl_exec($ch);
curl_close($ch);
```

{% endcode %}

</details>

**Response**

{% tabs %}
{% tab title="200" %}
{% code overflow="wrap" lineNumbers="true" %}

```json
{
  "ok": true
}
```

{% endcode %}
{% endtab %}

{% tab title="400" %}
{% code overflow="wrap" lineNumbers="true" %}

```json
{
  "ok": false,
  "error_code": 400,
  "description": "Too many updates. Max 1000"
}
```

{% endcode %}
{% endtab %}

{% tab title="Untitled" %}
{% code overflow="wrap" lineNumbers="true" %}

```json
{
  "ok": false,
  "error_code": 401,
  "description": "Unauthorized"
}
```

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

## For Developers

Develop an SDK in your programming language to integrate with Graspil. Publish the repository on GitHub and let us know at <mail@graspil.com>.

We’ll add a link to your repository in our documentation, bringing additional visitors to your page. Additionally, we can provide free access to a premium plan for several months and early access to our referral program.

[^1]: A standard [object](https://core.telegram.org/bots/api#update) with data from TG&#x20;
