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

# Webhooks

> Receive OPX webhooks notifications

Our system uses webhooks to notify external applications about important events occurring within our application.

They offer a simple and efficient way to receive real-time notifications when specific events happen in the OPX application. Instead of constantly polling our API to check for changes, webhooks allow your application to be instantly notified.

### Available events

#### Documents controlled `worksite_documents_controlled`

This webhook is triggered when all documents related to a worksite have been reviewed and validated.

```json theme={null}
{
    "event": "worksite_documents_controlled",
    "timestamp": "2024-03-21T10:00:00Z",
    "data": {
        "worksite_id": 123
    }
}
```

#### Document generated `worksite_documents_generated`

This webhook is triggered when a new document is generated for a worksite.

```json theme={null}
{
    "event": "worksite_document_generated",
    "timestamp": "2024-03-21T10:00:00Z",
    "data": {
        "worksite_id": 123,
        "document_id": 456
    }
}
```

#### Status changed `worksite_status_changed`

This webhook is triggered when a worksite status is updated.

```json theme={null}
{
    "event": "worksite_status_changed",
    "timestamp": "2024-03-21T10:00:00Z",
    "data": {
        "worksite_id": 123,
        "status_id": 4,
        "status": "Etape 4 : Etude finale du dossier"
    }
}
```

Available statuses are:

| status\_id | status                                             |
| ---------- | -------------------------------------------------- |
| -1         | Supprimé                                           |
| 0          | Annulé                                             |
| 1          | Etape 1 : Constitution de dossier                  |
| 2          | Etape 2 : Etude préliminaire du dossier            |
| 3          | Etape 3 : En attente des pièces finales            |
| 4          | Etape 4 : Etude finale du dossier                  |
| 5          | Etape 5 : Contrôles                                |
| 51         | Etape 5bis : Contrôle contact                      |
| 6          | Etape 6 : Dépôt auprès de l'administration         |
| 7          | Etape 7 : En attente du retour de l'administration |
| 8          | Etape 8 : Dossier terminé                          |

### Setup

#### Initial configuration

To start receiving webhooks, you must contact the OPX technical team. Two pieces of information will be required:

* **Receiving URL**: The HTTPS URL of your endpoint that will receive <u>all</u> the notifications.
* **Secret key**: A string of your choice that will be used to [secure](#security) the communication.

#### Receiving Webhooks

To correctly receive webhooks, your endpoint must:

* **Verify the authenticity** of the webhook using the `Signature` header.
* **Respond quickly** with an HTTP status code in the 2XX or 3XX range (within 3 seconds).
* **Handle processing asynchronously** if the logic takes longer to complete.

#### Security

Each webhook request includes a `Signature` header, which allows you to verify that the request was sent by OPX and not altered during transit.

The signature is generated using the **HMAC-SHA256** algorithm with your **Secret key**, and is computed over the raw body of the HTTP request.

Code example in PHP:

```php theme={null}
$signature = $_SERVER['HTTP_SIGNATURE'] ?? '';
$payload = file_get_contents('php://input');
$expectedSignature = hash_hmac('sha256', $payload, 'votre_secret');

if ($signature !== $expectedSignature) {
    http_response_code(401);
    exit('Invalid signature');
}

// Quick response
http_response_code(200);

// Async logic
```

Java:

```java theme={null}
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
sha256_HMAC.init(secret_key);

byte[] hash = sha256_HMAC.doFinal(payload.getBytes());
StringBuilder result = new StringBuilder();

for (byte b : hash) {
    result.append(String.format("%02x", b));
}

String computedSignature = "sha256=" + result.toString();

boolean matches = signature.equals(computedSignature);
```

#### Retry strategy

If your endpoint doesn't respond within 3 seconds or responds with an error code, our system will implement a retry strategy:

* 1st attempt: Retried after 10 seconds
* 2nd attempt: Retried after 100 seconds
* 3rd attempt: Retried after 1000 seconds
