# Document Synchronization Learn how to integrate your practice management system with Askara to receive and synchronize validated medical documents automatically. ## Overview When a healthcare professional validates a document in Askara, your system can receive the document and import it into your database. This guide explains the integration flow and available synchronization methods. ## Integration Flow 1. **Receive notification** - Via webhook (push) or polling (pull) 2. **Download document** - Get PDF and metadata via API 3. **Import to your system** - Save document and update your database 4. **Confirm status** - Report success or failure back to Askara ## Synchronization Methods ### Option 1: Webhooks (Recommended) Webhooks provide real-time notifications when documents are ready. Askara sends an HTTP POST request to your endpoint. **Advantages:** - Real-time synchronization - No polling overhead - Efficient resource usage #### Webhook Events Choose the event that best fits your workflow: | Event | When Triggered | Use Case | | --- | --- | --- | | `new_document` | Document is validated and ready | **Automatic sync** - Import documents immediately when ready | | `document_synchronize` | User manually initiates sync | **On-demand sync** - Wait for explicit user action before importing | **Choosing an Event:** - **Use `new_document`** if you want to automatically import all validated documents into your system as soon as they're ready. This provides the fastest synchronization with no user intervention required. - **Use `document_synchronize`** if you want users to explicitly trigger synchronization from Askara's interface. This gives healthcare professionals control over when documents are sent to your system. **Note:** You can register for both events if you want to support both automatic and manual synchronization modes. #### 1. Register Your Webhook **Endpoint:** `POST /webhooks` [→ API Reference: Create Webhook](/apis/askara-symfony/askara-api/webhook#create-webhook) **Example - Automatic sync:** ```json { "url": "https://your-system.com/api/askara/webhook", "events": ["new_document"], "active": true } ``` **Example - Manual sync:** ```json { "url": "https://your-system.com/api/askara/webhook", "events": ["document_synchronize"], "active": true } ``` **Example - Both modes:** ```json { "url": "https://your-system.com/api/askara/webhook", "events": ["new_document", "document_synchronize"], "active": true } ``` #### 2. Receive Webhook Events When an event occurs, Askara sends a POST request to your webhook URL. **Webhook Payload Structure:** ```json { "events": [{ "id": "document-uuid", "resource_type": "document", "action": "new_document", "metadata": { "document": { "uuid": "...", "type": "referral_letter", "state": "verified", "patient": { "uuid": "...", "externalId": "...", ... }, "pdf": { "url": "...", "fileName": "..." } } }, "resource_metadata": { "user_id": "...", "organization_id": "..." } }], "meta": { "webhook_id": "your-webhook-uuid" } } ``` **Important:** - Respond with `200 OK` within 5 seconds - Process the document asynchronously (download, import, confirm) - The payload structure is identical for both `new_document` and `document_synchronize` events - Check the `action` field to distinguish between events if you're subscribed to both #### 3. Download Document Data Use the document UUID to fetch full details if needed. **Endpoint:** `GET /documents/{uuid}` [→ API Reference: Get Document](/apis/askara-symfony/askara-api/document#get-document) The PDF URL in the webhook payload is pre-signed and valid for 1 hour. ### Option 2: Polling If webhooks aren't feasible, poll periodically for unsynchronized documents. **Endpoint:** `GET /documents?synchronized=false` [→ API Reference: List Documents](/apis/askara-symfony/askara-api/document#list-documents) **Query Parameters:** - `synchronized=false` - Returns only documents not yet synchronized with your client - `synchronized=true` - Returns only synchronized documents **Recommended polling interval:** 30-60 seconds **Response:** List of documents with embedded `pdf` and `patient` data. ## Confirming Synchronization Status **CRITICAL:** Always confirm the synchronization status after processing a document, whether it succeeded or failed. ### Report Success **Endpoint:** `POST /documents/{uuid}/status` [→ API Reference: Set Document Status](/apis/askara-symfony/askara-api/document#set-document-status) **Simple confirmation (recommended for most integrations):** ```json { "success": true } ``` **With optional tracking information:** ```json { "success": true, "directory": "your_software_id", "path": "C:\\YourSoftware\\Documents\\Patients\\DOE_JOHN\\document.pdf" } ``` **Fields:** - `success` *(required)* - `true` to mark synchronization as successful - `directory` *(optional)* - Your software identifier for internal tracking - `path` *(optional)* - Full file path where you saved the document for internal tracking This marks the document as synchronized and stops automatic retries. ### Report Failure Send the same request with `success: false` and provide an error message: ```json { "success": false, "error": "Failed to save document: Database connection timeout" } ``` **Fields:** - `success` *(required)* - `false` to indicate synchronization failed - `error` *(optional but recommended)* - Error message describing why synchronization failed - `directory` *(optional)* - Your software identifier - `path` *(optional)* - File path (usually empty on failure) **Important:** Always provide an `error` message when `success` is `false` to help troubleshoot synchronization issues. This records the failure with the error message. Healthcare professionals can then retry synchronization manually from Askara's interface. ## Retry Behavior ### Webhook Delivery Retries If your webhook endpoint fails to respond (network error, timeout, non-2xx status code), Askara automatically retries webhook delivery: - **Retry 1:** After 5 seconds - **Retry 2:** After 10 seconds - **Retry 3:** After 20 seconds - **Max retries:** 3 attempts After 3 failed attempts, the webhook delivery is marked as failed and stored in the failure queue. ### Document Synchronization Retries Document synchronization itself is **not retried automatically**. Retries are triggered: - **Manual retry:** Healthcare professionals can click "Synchronize" in Askara UI - **Rate limiting:** Manual retries are limited to once every 30 seconds to prevent abuse - **After success confirmation (`success: true`):** Document is marked as synchronized, no further retries needed - **After failure confirmation (`success: false`):** Document remains unsynchronized and can be retried manually ## Required OAuth2 Scopes To synchronize documents, your OAuth2 client must request these scopes: - `read:documents` - Retrieve document information - `write:document_integrations` - Confirm synchronization status [→ OAuth2 Guide](/guides/oauth2) ## Example Implementation ### Node.js Webhook Handler ```javascript app.post('/api/askara/webhook', async (req, res) => { // Respond quickly to avoid timeout res.status(200).send('OK'); const events = req.body.events; // Process asynchronously for (const event of events) { if (event.action === 'new_document' || event.action === 'document_synchronize') { const document = event.metadata.document; try { // Download PDF const pdfResponse = await fetch(document.pdf.url); const pdfBuffer = await pdfResponse.buffer(); // Save to your system const filePath = await saveToSystem(pdfBuffer, document); // Confirm success await fetch(`https://api.askara.ai/documents/${document.uuid}/status`, { method: 'POST', headers: { 'Authorization': `Bearer ${accessToken}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ success: true, directory: 'your_software_id', path: filePath }) }); } catch (error) { // Report failure await fetch(`https://api.askara.ai/documents/${document.uuid}/status`, { method: 'POST', headers: { 'Authorization': `Bearer ${accessToken}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ success: false, error: error.message }) }); } } } }); ``` ## Best Practices 1. **Always confirm status** - Report both successes and failures 2. **Provide error messages** - Include detailed error information when synchronization fails 3. **Process asynchronously** - Don't block webhook responses while processing 4. **Validate webhook signatures** - Verify requests come from Askara (if implemented) 5. **Handle duplicates** - Use document UUID to prevent duplicate imports 6. **Implement idempotency** - Same document UUID should produce the same result ## Troubleshooting ### Webhook Not Receiving Events - Verify your webhook URL is publicly accessible - Check that your endpoint responds with `200 OK` within 5 seconds - Review webhook logs in Askara dashboard - Ensure your firewall allows Askara's IP addresses ### Synchronization Failures - Check OAuth2 token hasn't expired - Verify you have the required scopes - Review error messages in document integration status - Test with polling method to isolate webhook issues ## Next Steps - **[API Reference](/apis/askara-symfony/askara-api)** - Explore all endpoints - **[OAuth2 Authentication](/guides/oauth2)** - Secure your integration - **[Rate Limiting](/guides/rate_limiting)** - Understand API limits - **[Support](https://www.askara.ai/en/contact)** - Get help with your integration