# Receiving Status Updates

To stay informed about the progress of dubbing processes, you can configure a callback URL.
For every status update related to an asset or its versions, Panjaya will send an HTTP `POST` request to the specified URL.
Each update includes the following details:
* **Asset ID**: The unique identifier for the asset. This field is always included.
* **Version ID**: The unique identifier for the version. This field is optional and is included only for
version-related events.
* **Version locale**: The target language of the version. This field is optional and is included only for version-related events.
* **Event type** specifies the type of event that occurred. Possible values are:
  * `asset_failed`: An error occurred while processing the asset. In this case, `version_id` field will be `null`.
  * `version_ready`: The version is ready for QC and additional editing in the workspace
  * `version_failed` An error occurred during the dubbing process for this version.
  * `version_generating` The version final video generation process has started.
  * `version_generated`: The version has been successfully generated. A URL to download the final video will be
provided in the `result_url` field in [Get Version](/apis/versions/versions-get_version) endpoint.
  * `version_generate_failed`: An error occurred during the video generation process.

### Signature verification
To ensure the authenticity of our callback requests, each request will include a signature in the `X-Signature` header.
The signature is calculated on the raw HTTP request's body, using the ES256 algorithm.
Optionally, you may use the `X-Signature` header to verify the authenticity of our request in your server.
Below is Panjaya's public key, to be used for verifying our callback's content:

```text
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZbUzbbuVyzSv7zVmH6rKypr6ojSS
/86W9dU6mwbdfAtUAx+QI7GNxl/4H1QV2BuBrysabh56O/YXhnFJMh7Lng==
-----END PUBLIC KEY-----
```
And here's an example of how to verify the signature in Python:

```python
import binascii
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.exceptions import InvalidSignature

PANJAYA_PUBLIC_KEY = '-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZbUzbbuVyzSv7zVmH6rKypr6ojSS\n/86W9dU6mwbdfAtUAx+QI7GNxl/4H1QV2BuBrysabh56O/YXhnFJMh7Lng==\n-----END PUBLIC KEY-----'
public_key = serialization.load_pem_public_key(PANJAYA_PUBLIC_KEY.encode())

def validate_panjaya_signature(request: Request) -> bool:
    raw_body = request.body()
    signature = request.headers.get("X-Signature")
    try:
        signature_bytes = binascii.unhexlify(signature)
        public_key.verify(signature_bytes, raw_body, ec.ECDSA(hashes.SHA256()))
        print("Signature is valid ✅")
        return True
    except InvalidSignature:
        print("Signature is invalid ❌")
        return False
```
Here's an example of the payload you can expect:

Endpoint: POST /callback

## Description:

  - `Signature verification` ()
    To ensure the authenticity of our callback requests, each request will include a signature in the X-Signature header. The signature is calculated on the raw HTTP request's body, using the ES256 algorithm. Optionally, you may use the X-Signature header to verify the authenticity of our request in your server. Below is Panjaya's public key, to be used for verifying our callback's content: -----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZbUzbbuVyzSv7zVmH6rKypr6ojSS
/86W9dU6mwbdfAtUAx+QI7GNxl/4H1QV2BuBrysabh56O/YXhnFJMh7Lng==
-----END PUBLIC KEY-----
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZbUzbbuVyzSv7zVmH6rKypr6ojSS
/86W9dU6mwbdfAtUAx+QI7GNxl/4H1QV2BuBrysabh56O/YXhnFJMh7Lng==
-----END PUBLIC KEY----- And here's an example of how to verify the signature in Python: import binascii
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.exceptions import InvalidSignature

PANJAYA_PUBLIC_KEY = '-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZbUzbbuVyzSv7zVmH6rKypr6ojSS\n/86W9dU6mwbdfAtUAx+QI7GNxl/4H1QV2BuBrysabh56O/YXhnFJMh7Lng==\n-----END PUBLIC KEY-----'
public_key = serialization.load_pem_public_key(PANJAYA_PUBLIC_KEY.encode())

def validate_panjaya_signature(request: Request) -> bool:
    raw_body = request.body()
    signature = request.headers.get("X-Signature")
    try:
        signature_bytes = binascii.unhexlify(signature)
        public_key.verify(signature_bytes, raw_body, ec.ECDSA(hashes.SHA256()))
        print("Signature is valid ✅")
        return True
    except InvalidSignature:
        print("Signature is invalid ❌")
        return False
import binascii
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.exceptions import InvalidSignature

PANJAYA_PUBLIC_KEY = '-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZbUzbbuVyzSv7zVmH6rKypr6ojSS\n/86W9dU6mwbdfAtUAx+QI7GNxl/4H1QV2BuBrysabh56O/YXhnFJMh7Lng==\n-----END PUBLIC KEY-----'
public_key = serialization.load_pem_public_key(PANJAYA_PUBLIC_KEY.encode())

def validate_panjaya_signature(request: Request) -> bool:
    raw_body = request.body()
    signature = request.headers.get("X-Signature")
    try:
        signature_bytes = binascii.unhexlify(signature)
        public_key.verify(signature_bytes, raw_body, ec.ECDSA(hashes.SHA256()))
        print("Signature is valid ✅")
        return True
    except InvalidSignature:
        print("Signature is invalid ❌")
        return False Here's an example of the payload you can expect:

## Header parameters:

  - `X-Signature` (string, required)
    ES256 signature of the request body. Can be used to verify the authenticity of the request.

  - `X-Signature-Algorithm` (string)

## Request fields (application/json):

  - `event` (string, required)
    Enum: "asset_failed", "version_ready", "version_failed", "version_generating", "version_generated", "version_generate_failed"

  - `asset_id` (string, required)

  - `version_id` (any)

  - `version_locale` (any)

## Response 200:

  - `200` (unknown)
    Successful Response

## Response 422:

  - `422` (unknown)
    Validation Error

## Response 422 fields (application/json):

  - `detail` (array)

  - `detail.loc` (array, required)

  - `detail.msg` (string, required)

  - `detail.type` (string, required)

  - `detail.input` (any)

  - `detail.ctx` (object)

