---
title: "ವೆಬ್‌ಹುಕ್ ಸಹಿಗಳನ್ನು ಪರಿಶೀಲಿಸಿ"
description: "ThunderPhone ಕಳುಹಿಸುವ ಪ್ರತಿಯೊಂದು ವೆಬ್‌ಹುಕ್ ಮತ್ತು ಉಪಕರಣ ವಿನಂತಿಗೆ ಸಹಿ ಮಾಡಲಾಗಿರುತ್ತದೆ. ಇಲ್ಲಿನ ಕ್ರಮವನ್ನು ಬಳಸಿ ಸಹಿಯನ್ನು ಒಮ್ಮೆ ಪರಿಶೀಲಿಸಿ, ನಂತರ ನೀವು ನಿರ್ವಹಿಸುವ ಪ್ರತಿಯೊಂದು ಎಂಡ್‌ಪಾಯಿಂಟ್‌ನಲ್ಲಿ ಅದೇ ಪರಿಶೀಲನೆಯನ್ನು ಮರುಬಳಸಿ."
---

ನಾವು ನಿಮ್ಮ ಸರ್ವರ್‌ಗೆ ಕಳುಹಿಸುವ ಪ್ರತಿಯೊಂದು ವಿನಂತಿಯು — ವೆಬಹುಕ್ ವಿತರಣೆಗಳು ಮತ್ತು ಟೂಲ್-ಎಂಡ್‌ಪಾಯಿಂಟ್ ಆಹ್ವಾನಗಳು — `X-ThunderPhone-Signature` ಹೆಡರ್‌ನಲ್ಲಿ HMAC-SHA256 ಸಹಿಯನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಪರಿಶೀಲನೆಯನ್ನು ಒಮ್ಮೆ ಸರಿಯಾಗಿ ಅಳವಡಿಸಿಕೊಳ್ಳಿ ಮತ್ತು ಅದೇ ಸಹಾಯಕವನ್ನು ಪ್ರತಿಯೊಂದು ಹ್ಯಾಂಡ್ಲರ್‌ಗೆ ಸೇರಿಸಿ.

## ಅಲ್ಗಾರಿದಮ್

1. **ಮೂಲ** ವಿನಂತಿ ಬಾಡಿಯನ್ನು ಓದಿ — ನಾವು ನಿಮಗೆ ಕಳುಹಿಸಿದ ನಿಖರ ಬೈಟ್‌ಗಳು.
2. `hmac_sha256(secret, body).hexdigest()` ಲೆಕ್ಕಹಾಕಿ.
3. `X-ThunderPhone-Signature` ವಿರುದ್ಧ **ಸ್ಥಿರ ಸಮಯದಲ್ಲಿ** ಹೋಲಿಸಿ.
   (ಸರಳ ಸ್ಟ್ರಿಂಗ್ ಹೋಲಿಕೆ ಸಮಯದ ಮಾಹಿತಿಯನ್ನು ಬಹಿರಂಗಪಡಿಸುತ್ತದೆ.)

ನಾವು ರವಾನಿಸುವ ನಿಖರ ಬೈಟ್‌ಗಳಿಗೇ ಸಹಿ ಮಾಡುತ್ತೇವೆ, ಆದ್ದರಿಂದ ಮೂಲ ಬಾಡಿಯನ್ನು ಪರಿಶೀಲಿಸುವುದು
ಯಾವಾಗಲೂ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ. ಆ ಬೈಟ್‌ಗಳು ಪೇಲೋಡ್‌ನ **ಮಾನದಂಡದ JSON ಸೀರಿಯಲೈಸೇಶನ್** ಕೂಡ ಆಗಿವೆ — ಕೀಗಳನ್ನು ವರ್ಣಮಾಲೆಯ ಕ್ರಮದಲ್ಲಿ ವಿಂಗಡಿಸಿ, ಸಂಕುಚಿತ ವಿಭಜಕಗಳೊಂದಿಗೆ
(ಖಾಲಿ ಸ್ಥಳಗಳಿಲ್ಲದ `,` ಮತ್ತು `:`), UTF-8. ನಿಮ್ಮ ಫ್ರೇಮ್‌ವರ್ಕ್ ಪಾರ್ಸ್ ಮಾಡಲಾದ JSON ಅನ್ನು ಮಾತ್ರ ಬಹಿರಂಗಪಡಿಸಿದಾಗ, ನಿಮಗೆ ಎರಡನೇ, ಸಂಪೂರ್ಣವಾಗಿ
ಸಮಾನವಾದ ವಿಧಾನ ದೊರೆಯುತ್ತದೆ: ಮಾನದಂಡದಂತೆ ಮರು-ಸೀರಿಯಲೈಸ್ ಮಾಡಿ ಮತ್ತು ಅದಕ್ಕೆ HMAC ಅನ್ವಯಿಸಿ.

```python
# Equivalent to hashing the raw body:
import json
canonical = json.dumps(payload, separators=(",", ":"), sort_keys=True).encode("utf-8")
```

ಮೂಲ ಬಾಡಿಗೇ ಆದ್ಯತೆ ನೀಡಿ — ಇದು ಒಂದು ಹಂತ ಕಡಿಮೆ ಮತ್ತು ಕೆಲವು ಭಾಷೆಗಳಲ್ಲಿನ JSON ಸಂಖ್ಯೆಗಳ
ಮರುಪರಿವರ್ತನೆಯ ವೈಶಿಷ್ಟ್ಯಗಳಿಂದ ಪ್ರಭಾವಿತವಾಗುವುದಿಲ್ಲ.

## ಯಾವ ರಹಸ್ಯ?

| ಮೂಲ | ರಹಸ್ಯ |
|--------|--------|
| [ವೆಬಹುಕ್ ಎಂಡ್‌ಪಾಯಿಂಟ್](/kn/webhooks/endpoints) (`/v1/developer/webhook-endpoints`) | ರಚಿಸುವಾಗ ಒಮ್ಮೆ ಹಿಂತಿರುಗಿಸಲಾದ ಪ್ರತಿಯೊಂದು ಎಂಡ್‌ಪಾಯಿಂಟ್‌ನ `secret` (48 ಹೆಕ್ಸ್ ಅಕ್ಷರಗಳು) |
| [ಪಾರಂಪರಿಕ ಏಕ-URL ವೆಬಹುಕ್](/api-reference/organizations#legacy-single-url-webhook) | `GET /v1/webhook` ನಲ್ಲಿ ಹಿಂತಿರುಗಿಸಲಾದ ಪ್ರತಿಯೊಂದು ಸಂಸ್ಥೆಯ `secret` |
| [ಟೂಲ್-ಎಂಡ್‌ಪಾಯಿಂಟ್ ಆಹ್ವಾನ](/kn/tools/overview) (ನಿಮ್ಮ `endpoint.url` ಗೆ ನೇರ ಕರೆ) | **ಸಂಸ್ಥೆ-ಮಟ್ಟದ ವೆಬಹುಕ್ ರಹಸ್ಯ** (ಪಾರಂಪರಿಕ ಏಕ-URL ವೆಬಹುಕ್‌ನದ್ದೇ) — ಎಂಡ್‌ಪಾಯಿಂಟ್-ಪ್ರತ್ಯೇಕ ರಹಸ್ಯವಲ್ಲ |

ರಹಸ್ಯವನ್ನು ನಿಮ್ಮ ರಹಸ್ಯ ನಿರ್ವಾಹಕ ಅಥವಾ ಪರಿಸರ ಚರದಲ್ಲಿ ಸಂಗ್ರಹಿಸಿ — ಅದನ್ನು ಎಂದಿಗೂ ಕಮಿಟ್ ಮಾಡಬೇಡಿ.

## ಉಲ್ಲೇಖ ಅನುಷ್ಠಾನಗಳು

ಎಲ್ಲ ನಾಲ್ಕೂ ಮೂಲ ವಿನಂತಿ ಬಾಡಿಯನ್ನು ಪರಿಶೀಲಿಸುತ್ತವೆ:

<CodeGroup>
```python Python
import hashlib
import hmac


def verify(body: bytes, signature: str, secret: str) -> bool:
    """Constant-time HMAC-SHA256 verification."""
    expected = hmac.new(
        secret.encode("utf-8"),
        body,
        hashlib.sha256,
    ).hexdigest()
    return hmac.compare_digest(expected, signature or "")
```

```javascript Node.js
import crypto from "node:crypto";

export function verify(body, signature, secret) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(body)
    .digest("hex");
  if (!signature || expected.length !== signature.length) return false;
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature),
  );
}
```

```go Go
package webhook

import (
    "crypto/hmac"
    "crypto/sha256"
    "encoding/hex"
)

func Verify(body []byte, signature, secret string) bool {
    mac := hmac.New(sha256.New, []byte(secret))
    mac.Write(body)
    expected := hex.EncodeToString(mac.Sum(nil))
    return hmac.Equal([]byte(expected), []byte(signature))
}
```

```ruby Ruby
require "openssl"

def verify(body, signature, secret)
  expected = OpenSSL::HMAC.hexdigest("SHA256", secret, body)
  Rack::Utils.secure_compare(expected, signature.to_s)
end
```
</CodeGroup>

## ಫ್ರೇಮ್‌ವರ್ಕ್-ನಿರ್ದಿಷ್ಟ ಸಂಪರ್ಕಣೆ

<CodeGroup>
```python FastAPI
from fastapi import FastAPI, HTTPException, Request

app = FastAPI()

@app.post("/thunderphone-webhook")
async def hook(request: Request):
    body = await request.body()           # raw bytes, NOT request.json()
    sig = request.headers.get("X-ThunderPhone-Signature", "")
    if not verify(body, sig, SECRET):
        raise HTTPException(status_code=401)

    import json
    event = json.loads(body)
    # … dispatch on event["type"] …
    return {"ok": True}
```

```javascript Express
import express from "express";

const app = express();

app.post(
  "/thunderphone-webhook",
  // IMPORTANT: parse as raw; do NOT use express.json() here.
  express.raw({ type: "application/json" }),
  (req, res) => {
    const sig = req.header("X-ThunderPhone-Signature") || "";
    if (!verify(req.body, sig, process.env.WEBHOOK_SECRET)) {
      return res.sendStatus(401);
    }
    const event = JSON.parse(req.body.toString("utf8"));
    // … dispatch on event.type …
    res.sendStatus(204);
  },
);
```

```python Django
import json

from django.http import JsonResponse, HttpResponseForbidden
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST


@csrf_exempt
@require_POST
def hook(request):
    body = request.body  # raw bytes
    sig = request.headers.get("X-ThunderPhone-Signature", "")
    if not verify(body, sig, SECRET):
        return HttpResponseForbidden("invalid signature")
    event = json.loads(body)
    # … dispatch on event["type"] …
    return JsonResponse({"ok": True})
```
</CodeGroup>

## ಟೂಲ್ ಕರೆಗಳನ್ನು ಪರಿಶೀಲಿಸುವುದು

ಏಜೆಂಟ್ ನಿಮ್ಮ [ಫಂಕ್ಷನ್ ಟೂಲ್‌ಗಳಲ್ಲಿ](/kn/tools/overview) ಒಂದನ್ನು ನೇರವಾಗಿ
ಆಹ್ವಾನಿಸಿದಾಗ (ಟೂಲ್‌ಗೆ `endpoint` ಇರುವಾಗ), ವಿನಂತಿಯು ನೀವು ಕಾನ್ಫಿಗರ್
ಮಾಡಿರುವ `endpoint.headers` ಜೊತೆಗೆ ಎರಡು ThunderPhone ಹೆಡರ್‌ಗಳನ್ನು
ಒಳಗೊಂಡಿರುತ್ತದೆ:

- `X-ThunderPhone-Call-ID` — ಲೈವ್ ಕರೆಯ ಸಂಖ್ಯಾ ಐಡಿ.
- `X-ThunderPhone-Signature` — ನಿಖರವಾದ ವಿನಂತಿ-ಬಾಡಿ ಬೈಟ್‌ಗಳ ಮೇಲೆ ನಿಮ್ಮ
  **ಸಂಸ್ಥೆ-ಮಟ್ಟದ ವೆಬ್‌ಹುಕ್ ಸೀಕ್ರೆಟ್** ಬಳಸಿ ಕೀ ಮಾಡಲಾದ HMAC-SHA256.

ಅದೇ `verify()` ಹೆಲ್ಪರ್ ಯಾವುದೇ ಬದಲಾವಣೆ ಇಲ್ಲದೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ, ಆದರೆ
ಎರಡು ಸೂಕ್ಷ್ಮತೆಗಳಿವೆ:

1. **`GET` / `DELETE` ಟೂಲ್‌ಗಳಿಗೆ ಬಾಡಿ ಇರುವುದಿಲ್ಲ.** ಆರ್ಗ್ಯುಮೆಂಟ್‌ಗಳು ಕ್ವೆರಿ
   ಪ್ಯಾರಾಮೀಟರ್‌ಗಳಾಗಿ ಸಾಗುತ್ತವೆ ಮತ್ತು ಸಿಗ್ನೇಚರ್ ಅನ್ನು **ಖಾಲಿ ಬೈಟ್
   ಸ್ಟ್ರಿಂಗ್** ಮೇಲೆ ಲೆಕ್ಕಹಾಕಲಾಗುತ್ತದೆ — ಆದ್ದರಿಂದ `verify(b"", sig, secret)`
   (Python) ಅಥವಾ `verify(Buffer.alloc(0), sig, secret)` (Node) ಬಳಸಿ. ಕ್ವೆರಿ
   ಸ್ಟ್ರಿಂಗ್ ಅನ್ನು ಹ್ಯಾಶ್ ಮಾಡಬೇಡಿ.
2. **ಲೆಗಸಿ ವೆಬ್‌ಹುಕ್ ಕಾನ್ಫಿಗರ್ ಮಾಡದ ಸಂಸ್ಥೆಗಳಿಗೆ ಸಂಸ್ಥೆಯ ಸೀಕ್ರೆಟ್
   ಇರುವುದಿಲ್ಲ.** ಆ ಸಂದರ್ಭದಲ್ಲಿ ಟೂಲ್ ಕರೆಗಳು ಕೇವಲ `X-ThunderPhone-Call-ID`
   ಅನ್ನು ಹೊಂದಿರುತ್ತವೆ; ಸಿಗ್ನೇಚರ್ ಹೆಡರ್ ಇರುವುದಿಲ್ಲ. ಸೈನಿಂಗ್ ಸೀಕ್ರೆಟ್ ಪಡೆಯಲು
   ಲೆಗಸಿ ವೆಬ್‌ಹುಕ್ ಅನ್ನು (`PUT /v1/webhook`) ಕಾನ್ಫಿಗರ್ ಮಾಡಿ, ಅಥವಾ
   `endpoint.headers` ಮೂಲಕ ನಿಮ್ಮ ಸ್ವಂತ ಹೆಡರ್ ಬಳಸಿ ಟೂಲ್ ಕರೆಗಳನ್ನು
   ದೃಢೀಕರಿಸಿ.

```python
@app.post("/tools/search-appointments")
async def tool(request: Request):
    body = await request.body()  # b"" for GET/DELETE tools
    sig = request.headers.get("X-ThunderPhone-Signature", "")
    call_id = request.headers.get("X-ThunderPhone-Call-ID", "")
    if not verify(body, sig, ORG_WEBHOOK_SECRET):
        raise HTTPException(status_code=401)
    args = json.loads(body)
    ...
```

ವೆಬ್‌ಹುಕ್-**ಮೋಡ್** ಟೂಲ್ ಡಿಸ್ಪ್ಯಾಚ್‌ಗೆ (`endpoint` ಇಲ್ಲದ, ನಿಮ್ಮ ಸಂಸ್ಥೆಯ
ವೆಬ್‌ಹುಕ್‌ಗೆ `telephony.tool` / `web.tool` ಆಗಿ ತಲುಪಿಸುವ ಟೂಲ್‌ಗಳು) ಸಾಮಾನ್ಯ
ಸಹಿ ಮಾಡಿದ ವೆಬ್‌ಹುಕ್ ಅನ್ವಯಿಸುತ್ತದೆ — ಮೇಲಿನ ಪ್ರಮಾಣಿತ ವಿಧಾನವನ್ನು ಬಳಸಿ.
ಎರಡೂ ವಿನಂತಿ ಸ್ವರೂಪಗಳಿಗಾಗಿ [ಫಂಕ್ಷನ್ ಟೂಲ್‌ಗಳನ್ನು](/kn/tools/overview) ನೋಡಿ.

## ಸಾಮಾನ್ಯ ತಪ್ಪುಗಳು

<AccordionGroup>
  <Accordion title="ಡೀಫಾಲ್ಟ್ ಫಾರ್ಮ್ಯಾಟಿಂಗ್‌ನೊಂದಿಗೆ ಮರು-ಸೀರಿಯಲೈಸ್ ಮಾಡುವುದು">
    ಬಾಡಿಯನ್ನು ಪಾರ್ಸ್ ಮಾಡಿ ನಿಮ್ಮ JSON ಲೈಬ್ರರಿಯ ಡೀಫಾಲ್ಟ್‌ಗಳೊಂದಿಗೆ
    ಮರು-ಡಂಪ್ ಮಾಡುವುದರಿಂದ (`,` / `:` ನಂತರದ ಖಾಲಿ ಜಾಗಗಳು, ಸೇರಿಸಿದ ಕ್ರಮದ ಕೀಲಿಗಳು)
    ವಿಭಿನ್ನ ಬೈಟ್‌ಗಳು ಉತ್ಪತ್ತಿಯಾಗುತ್ತವೆ ಮತ್ತು HMAC ವಿಫಲಗೊಳ್ಳುತ್ತದೆ. ಮೂಲ ಬಾಡಿಯನ್ನು ಪರಿಶೀಲಿಸಿ — ಅಥವಾ ನೀವು
    ಮರು-ಸೀರಿಯಲೈಸ್ ಮಾಡಲೇಬೇಕಾದರೆ, ನಮ್ಮ ಪ್ರಮಾಣಿತ ರೂಪಕ್ಕೆ ನಿಖರವಾಗಿ ಹೊಂದಿಸಿ: ವಿಂಗಡಿಸಿದ
    ಕೀಲಿಗಳು, ಸಂಕ್ಷಿಪ್ತ ವಿಭಜಕಗಳು, UTF-8.
  </Accordion>

  <Accordion title="ಫ್ರೇಮ್‌ವರ್ಕ್ JSON ಅನ್ನು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಪಾರ್ಸ್ ಮಾಡುತ್ತದೆ">
    Express ನ `express.json()` ಮಿಡಲ್‌ವೇರ್ ಬಾಡಿ ಸ್ಟ್ರೀಮ್ ಅನ್ನು
    ಬಳಸಿಕೊಳ್ಳುತ್ತದೆ ಮತ್ತು ನೀವು ಮೂಲ ಬೈಟ್‌ಗಳನ್ನು ಕಳೆದುಕೊಳ್ಳುತ್ತೀರಿ. ವೆಬ್‌ಹುಕ್
    ರೂಟ್‌ನಲ್ಲಿ ನಿರ್ದಿಷ್ಟವಾಗಿ `express.raw()` ಬಳಸಿ, ಅಥವಾ ಪೂರ್ವ-ಮಿಡಲ್‌ವೇರ್‌ನಲ್ಲಿ ಮೂಲ ಬಾಡಿಯನ್ನು ಬಫರ್ ಮಾಡಿ.
    NestJS / Koaಗೂ ಇದೇ ಅನ್ವಯಿಸುತ್ತದೆ — ಅವುಗಳ "ಮೂಲ ಬಾಡಿ" ದಾಖಲೆಗಳನ್ನು ಪರಿಶೀಲಿಸಿ.
  </Accordion>

  <Accordion title="ಸಮಯ-ಸುರಕ್ಷಿತವಲ್ಲದ ಹೋಲಿಕೆ">
    JS ನಲ್ಲಿ `expected === signature` ಅಥವಾ Python ನಲ್ಲಿ `expected == signature`
    ಸಮಯಕ್ಕೆ ಅನುಗುಣವಾಗಿ ಬದಲಾಗುವ ಹೋಲಿಕೆಗಳಾಗಿವೆ. ಕ್ರಮವಾಗಿ `crypto.timingSafeEqual`
    ಅಥವಾ `hmac.compare_digest` ಬಳಸಿ. ಕಾರ್ಯಕ್ಷಮತೆಯ ವ್ಯತ್ಯಾಸ
    ಶೂನ್ಯವಾಗಿದೆ.
  </Accordion>

  <Accordion title="ಟೂಲ್ ಎಂಡ್‌ಪಾಯಿಂಟ್‌ಗಳಿಗೆ ತಪ್ಪು ರಹಸ್ಯ">
    ನೇರ ಟೂಲ್-ಎಂಡ್‌ಪಾಯಿಂಟ್ ಕರೆಗಳಿಗೆ **ಸಂಸ್ಥೆ-ಮಟ್ಟದ ವೆಬ್‌ಹುಕ್
    ರಹಸ್ಯ** (`GET /v1/webhook`) ಬಳಸಿ ಸಹಿ ಮಾಡಲಾಗುತ್ತದೆ — 
    `/v1/developer/webhook-endpoints` ನಲ್ಲಿನ ಯಾವುದೇ ಪ್ರತಿ-ಎಂಡ್‌ಪಾಯಿಂಟ್ ರಹಸ್ಯವನ್ನು ಬಳಸಲಾಗುವುದಿಲ್ಲ. ಅದೇ `verify()`
    ಫಂಕ್ಷನ್ ಅನ್ನು ಮರುಬಳಸಿ, ಆದರೆ ಟೂಲ್ ರೂಟ್‌ಗಳಲ್ಲಿ ಅದಕ್ಕೆ ಸಂಸ್ಥೆಯ ರಹಸ್ಯವನ್ನೇ ನೀಡುತ್ತಿರುವುದನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ.
  </Accordion>

  <Accordion title="GET/DELETE ಟೂಲ್‌ಗಳಲ್ಲಿ ಕ್ವೆರಿ ಸ್ಟ್ರಿಂಗ್ ಅನ್ನು ಹ್ಯಾಶ್ ಮಾಡುವುದು">
    ಬಾಡಿಯಿಲ್ಲದ ಟೂಲ್ ವಿಧಾನಗಳಿಗೆ ಸಹಿಯು ಖಾಲಿ ಬೈಟ್
    ಸ್ಟ್ರಿಂಗ್ ಅನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ, ಇದರಿಂದ ಒಂದೇ ಸಾರ್ವತ್ರಿಕ ವಿಧಾನ ಉಳಿಯುತ್ತದೆ: ಮೂಲ ವಿನಂತಿ ಬಾಡಿ ಏನೇ ಇದ್ದರೂ
    ಅದಕ್ಕೆ HMAC ಮಾಡಿ. URL ಅಥವಾ ಕ್ವೆರಿ ಸ್ಟ್ರಿಂಗ್ ಅನ್ನು ಹ್ಯಾಶ್ ಮಾಡಿದರೆ ಎಂದಿಗೂ ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ.
  </Accordion>

  <Accordion title="ಹೊಂದಿಕೆಯಾಗದಾಗ 401 ಹಿಂತಿರುಗಿಸದಿರುವುದು">
    ಪರಿಶೀಲನೆ ವಿಫಲವಾದಾಗ 200 ಹಿಂತಿರುಗಿಸುವುದು ಹ್ಯಾಂಡ್ಲರ್ ಅನ್ನು ಮರುಕಳುಹಿಸುವ ದಾಳಿಯ
    ಗುರಿಯನ್ನಾಗಿಸುತ್ತದೆ. ಪರಿಶೀಲನೆ ವಿಫಲವಾದರೆ ಯಾವಾಗಲೂ 2xx ಅಲ್ಲದ ಪ್ರತಿಕ್ರಿಯೆ ನೀಡಿ.
  </Accordion>
</AccordionGroup>

---

## ಮುಂದಿನ ಹಂತಗಳು

<CardGroup cols={2}>
  <Card title="ವೆಬ್‌ಹುಕ್ ಅವಲೋಕನ" icon="bolt" href="/kn/webhooks/overview">
    ವಿತರಣೆಯ ವರ್ತನೆ, ಮರುಪ್ರಯತ್ನಗಳು, ಮೂಲ IPಗಳು.
  </Card>
  <Card title="ವೆಬ್‌ಹುಕ್ ಎಂಡ್‌ಪಾಯಿಂಟ್‌ಗಳು" icon="plug" href="/kn/webhooks/endpoints">
    ಬಹು URLಗಳನ್ನು ನಿರ್ವಹಿಸಿ, ರಹಸ್ಯಗಳನ್ನು ಬದಲಾಯಿಸಿ.
  </Card>
  <Card title="ಫಂಕ್ಷನ್ ಟೂಲ್‌ಗಳು" icon="screwdriver-wrench" href="/kn/tools/overview">
    ಎರಡು ಟೂಲ್-ಆಹ್ವಾನ ಮಾರ್ಗಗಳು ಮತ್ತು ಅವುಗಳ ವಿನಂತಿ ರೂಪಗಳು.
  </Card>
  <Card title="ಟೂಲ್ ಏಕೀಕರಣಗಳು" icon="wrench" href="/kn/guides/build-tool-integration">
    ಸಂಪೂರ್ಣ ಟೂಲ್-ಆಧಾರಿತ ಏಕೀಕರಣವನ್ನು ಆರಂಭದಿಂದ ಅಂತ್ಯದವರೆಗೆ ನಿರ್ಮಿಸಿ.
  </Card>
</CardGroup>
