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

# Kovi Webhooks: Real-Time Interview Scorecard Delivery

> Kovi posts a structured JSON scorecard to your webhook endpoint the moment an interview concludes—enabling real-time ATS updates and hiring decisions.

Kovi uses webhooks to deliver interview scorecards in real time. When a candidate completes an interview, Kovi immediately sends a POST request containing the full scorecard to your configured HTTPS endpoint—no polling required.

## How Webhooks Work

When an interview finishes, Kovi executes the following sequence automatically:

1. **Interview concludes.** The candidate submits their final response and Kovi finalises the evaluation.
2. **Kovi prepares the scorecard JSON.** Scores, proctoring flags, strengths, weaknesses, and the transcript URL are assembled into a structured payload.
3. **Kovi sends an HTTP POST to your configured endpoint.** The request is dispatched within seconds of interview completion.
4. **Your server receives and processes the payload.** Parse the JSON body and extract the fields relevant to your workflow.
5. **Update your ATS or database.** Write the scorecard data to your candidate record, trigger downstream notifications, or automate next-stage scheduling.

## Setting Up Your Webhook URL

<Steps>
  <Step title="Log in to the Techeval dashboard">
    Navigate to [techeval.ai](https://techeval.ai) and sign in with your account credentials.
  </Step>

  <Step title="Go to Settings → Integrations">
    Open the **Settings** menu from the top navigation bar and select **Integrations**.
  </Step>

  <Step title="Enter your HTTPS webhook URL">
    Paste your publicly reachable HTTPS endpoint URL into the **Webhook URL** field.

    <Warning>
      Your webhook endpoint must be publicly reachable over HTTPS. HTTP endpoints and private/localhost URLs are not accepted.
    </Warning>
  </Step>

  <Step title="(Optional) Add a shared secret token for verification">
    Enter a secret token in the **Shared Secret** field. Kovi will include this value in every request header so your server can verify the payload's authenticity. See the [Security](#security) section below for a verification example.
  </Step>

  <Step title="Click Save and send a test delivery">
    Click **Save**, then use the **Send Test** button to trigger a sample payload delivery to your endpoint and confirm it is receiving requests correctly.

    <Note>
      Test deliveries from the dashboard do not consume interview credits.
    </Note>
  </Step>
</Steps>

## Delivery Guarantees

Kovi is designed to make sure your endpoint receives every scorecard reliably:

* **Immediate dispatch.** The webhook is triggered the instant an interview is marked complete—there is no scheduled batch window or delay.
* **Automatic retries.** If your endpoint returns a non-2xx HTTP status code, Kovi retries the delivery up to **3 times** using exponential backoff (approximately 30 s, 2 min, and 8 min between attempts).
* **Respond quickly.** Your endpoint should return a 2xx response within **10 seconds**. If processing takes longer, acknowledge the request immediately and handle the payload asynchronously.

<Info>
  If all three retry attempts fail, the failed delivery is logged in the Techeval dashboard under **Settings → Integrations → Delivery Logs** so you can inspect the error and manually re-trigger delivery.
</Info>

## Security

When you configure a shared secret token, Kovi includes it in every webhook request using the `X-Kovi-Secret` header. Always validate this header before processing the payload to ensure the request genuinely originates from Kovi.

```python webhook_receiver.py theme={null}
from flask import Flask, request, abort

app = Flask(__name__)

KOVI_SECRET = "your_shared_secret_token_here"

@app.route("/kovi/webhook", methods=["POST"])
def kovi_webhook():
    # Retrieve the secret header sent by Kovi
    received_secret = request.headers.get("X-Kovi-Secret")

    # Reject the request if the header is missing or does not match
    if received_secret != KOVI_SECRET:
        abort(403)

    payload = request.get_json()

    # Process the scorecard payload
    candidate_id = payload.get("candidate_id")
    final_score = payload.get("final_score")
    passed = payload.get("passed_threshold")

    print(f"Scorecard received — Candidate: {candidate_id}, Score: {final_score}, Passed: {passed}")

    # Return 200 to acknowledge receipt
    return "", 200
```

For the complete list of fields in the POST body, see the [Scorecard Payload Reference](/webhooks/scorecard-payload).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.