# Certn API Documentation - Webhooks

> Source: https://centric-api-docs.certn.co/#webhooks
> Interactive docs: https://centric-api-docs.certn.co/#webhooks

## Webhooks

The Certn platform can notify your systems when particular events occur by sending webhooks. You can configure webhook URLs in the Integrations area of the Client Portal.

### Event Types

| Event Code | Description |
|------------|-------------|
| `CASE_STATUS_CHANGED` | The status of a case has changed. Track progress during a case's lifecycle. |
| `CHECK_STATUS_CHANGED` | The status of an individual check has changed. Receive real-time updates on check progress. |
| `CASE_REPORT_READY` | The case report you requested has been generated and is ready to retrieve. |
| `CASE_INPUT_CLAIMS_AUTOMATICALLY_GENERATED` | A case has new input claims automatically generated by Certn (only for some quickscreen checks). |

### Webhook Payload

#### Case status changed (CASE_STATUS_CHANGED)

Sent when a case's overall status changes. `object_type` is `CASE` and `case_status` reflects the case's combined check status.

```json
{
  "created": "2024-06-27T12:00:00Z",
  "event_id": "e50b8c4f-9a95-40a0-886a-37aa21ea078e",
  "event_type": "CASE_STATUS_CHANGED",
  "object_id": "2f64d134-1c54-4028-8e8b-9cfa7bd8011c",
  "object_type": "CASE",
  "case_status": "IN_PROGRESS"
}
```

#### Check status changed (CHECK_STATUS_CHANGED)

Sent when an individual check's status changes. Includes `triggered_check`; when a check needs client action, `action_required_resolution` describes the steps to resolve it.

```json
{
  "created": "2024-06-27T12:00:00Z",
  "event_id": "e50b8c4f-9a95-40a0-886a-37aa21ea078e",
  "event_type": "CHECK_STATUS_CHANGED",
  "object_id": "2f64d134-1c54-4028-8e8b-9cfa7bd8011c",
  "object_type": "CASE",
  "case_status": "CLIENT_ACTION_REQUIRED",
  "triggered_check": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "type": "UK_MANUAL_IDENTITY_VERIFICATION_1",
    "status": "CLIENT_ACTION_REQUIRED",
    "action_required_resolution": {
      "summary": "Complete UK Manual Identity Verification for the paired criminal check.",
      "step_count": 2,
      "steps": [
        {
          "step": 1,
          "instruction": "Upload each required identity document",
          "id": "upload_file",
          "http_method": "POST",
          "path": "/api/public/files/upload/"
        },
        {
          "step": 2,
          "instruction": "Submit verification details",
          "id": "respond",
          "http_method": "POST",
          "path": "/api/public/cases/{case_id}/checks/{check_id}/respond/"
        }
      ]
    }
  }
}
```

#### Case report ready (CASE_REPORT_READY)

Sent when the case report you requested has been generated and is ready to retrieve.

```json
{
  "created": "2024-06-27T12:00:00Z",
  "event_id": "3c2f1a9d-7b54-4e21-9f0c-5d6a8b3e21fa",
  "event_type": "CASE_REPORT_READY",
  "object_id": "2f64d134-1c54-4028-8e8b-9cfa7bd8011c",
  "object_type": "CASE",
  "case_status": "COMPLETE"
}
```

#### Case input claims automatically generated (CASE_INPUT_CLAIMS_AUTOMATICALLY_GENERATED)

Sent when Certn automatically generates new input claims for a case (only for some quickscreen checks).

```json
{
  "created": "2024-06-27T12:00:00Z",
  "event_id": "9f0c5d6a-8b3e-21fa-3c2f-1a9d7b544e21",
  "event_type": "CASE_INPUT_CLAIMS_AUTOMATICALLY_GENERATED",
  "object_id": "2f64d134-1c54-4028-8e8b-9cfa7bd8011c",
  "object_type": "CASE",
  "case_status": "IN_PROGRESS"
}
```

### Endpoint Verification (Required)

**Webhook Validation Requirement**: You **must** implement endpoint verification within **10 seconds**. If verification fails, webhook delivery will be disabled.

When you add a webhook URL, our system sends a GET request with a `challenge` parameter. Your app must echo back the challenge value as the response body.

**Flask:**
```python
@app.get('/certn-webhook/')
def verify():
    return request.args["challenge"], {
        "Content-Type": "text/plain",
        "X-Content-Type-Options": "nosniff",
    }
```

**Express:**
```javascript
app.get('/certn-webhook', (req, res) => {
  res.set('Content-Type', 'text/plain');
  res.set('X-Content-Type-Options', 'nosniff');
  res.send(req.query.challenge);
});
```

### Payload Signature Verification (Recommended)

Webhook requests include an `X-Signature` header containing an HMAC-SHA256 signature of the request body. The signing key is provided when you create the webhook configuration.

```python
from hashlib import sha256
import hmac

@app.post("/certn-webhook/")
def webhook():
    signature = request.headers.get("X-Signature")
    expected = hmac.new(WEBHOOK_SECRET, request.data, sha256).hexdigest()
    if not hmac.compare_digest(signature, expected):
        abort(403)

    payload = request.json
    # Process webhook...
    return "", 200
```

### Best Practices

- **Respond quickly**: Return a 200 response within 10 seconds. Process webhook data asynchronously in a background job.
- **Retry behavior**: Failed deliveries are retried with exponential backoff (30s, 90s, 270s, etc.) for approximately 2 hours.
- **Handle out-of-order delivery**: Due to retries, you may receive webhooks out of order. Design your system to handle this.
- **Deduplicate events**: Each webhook has a unique `event_id`. Store processed event IDs to avoid processing the same event twice.

---

## Additional Resources

- [Interactive Documentation](https://centric-api-docs.certn.co)
- [OpenAPI Specification](https://centric-api-docs.certn.co/openapi.yaml)
- [All Reference Docs](https://centric-api-docs.certn.co/reference/)

*Generated from Certn API Documentation*