About the SuraqHub Platform Introduction

SuraqHub is an enterprise, fault-tolerant platform for designing interactive electronic forms, running surveys, collecting structured data, validating it, scanning it for viruses and feeding it to external analytical stores in real time.

⚡ Key Capabilities
  • Visual builder supporting more than 30 component types, responsive grids and formulas (full guide).
  • Antivirus protection: every uploaded file is quarantined and scanned by ClamAV before it reaches the storage.
  • Asynchronous architecture: exporting hundreds of thousands of forms to Excel (XLSX) runs in the background via RabbitMQ.
  • Enterprise-grade integrations: synchronous GraphQL API with M2M keys, instant webhooks with HMAC-SHA256 cryptographic signatures, and a pull analytics channel for Power BI through a dedicated database schema.
  • Standards compliance: light/dark themes, WCAG 2.2 AA accessibility and strict Content Security Policy (CSP) rules.

Concepts and Core Entities Architecture

The SuraqHub architecture is built on a clear separation between the structure of questions (the schema) and the entry point to a survey (the publication):

📝 Form Schema

A JSON structure describing questions, validation, field types, dropdown lists and conditional logic. Schemas are immutable: every save creates a new revision in the version history, which guarantees the integrity of already collected responses.

🌐 Publication

The configuration of the survey web page. It contains the Slug (a human-readable address such as /f/feedback), availability status (Active / Inactive), branding (Header, Footer), the design theme and a link to a specific version of the form schema.

💡 Benefit of the separation:

You can build and test new versions of a form in advance, then switch the publication to the new version with a single click — no user downtime and no change to the public link.

Form Creation Life Cycle Workflow

The standard workflow from an idea to finished reports consists of 5 steps:

  1. Create a publication (the "General" screen): set the survey title and its future web address (Slug).
  2. Build the questions (the "Builder" screen): assemble the field structure, configure requiredness, hints and display logic.
  3. Branding and localization (the "Design" and "Translations" screens): configure the company header, footer and add Kazakh/English translations.
  4. Preview and verify (the "Preview" screen): fill in a test survey, make sure calculations and validation behave correctly.
  5. Activate and collect responses: turn on the "Status: Active" toggle and analyze the results on the "Reporting" screen or via Webhooks/API.

The "General" Section (Publication Management) Screen

The central screen for monitoring all published surveys and managing revisions.

Controls

  • "New publication" button: clears the creation form and switches the manager into registration mode for a new address.
  • Search (live filter): instantly filters the publication list by title or slug.
  • "Publication title" field: the name shown to users in the browser tab title and in the survey header.
  • "URL (Address)" field / Slug: a unique Latin-alphabet string (for example, anketa-2026). The final link to the form: https://domain/f/anketa-2026.
  • "Status: Active" toggle: when off, users attempting to fill in the form see the "acceptance closed" screen (Inactive Screen).
  • Revision history and Rollback: the lower part of the card shows a timeline of all saved versions with date and author. Clicking a revision instantly loads the historical version of the form into the builder.

Administrative Publication List

Administrators get a cross-platform "Publications" list covering every survey on the platform, including those created by other users:

  • Search: by publication title, slug or form title.
  • Filters: status (active/inactive), access type (public, private, role-based) and owner.
  • Actions: open any publication for editing, activate/deactivate; the table shows the response count and the acceptance end date.
  • Creators without the administrator role see only their own publications in the "General" section.

The "Form Builder" Section Screen

A visual drag-and-drop editor for digital forms and interactive surveys.

Workspace Layout

  • Left component palette: contains basic fields (Text, Number, Checkbox, Files) and layout elements (Panels, Columns). Drag them with the mouse into the work area on the right. A full reference of all components is available in the builder guide.
  • Working canvas: displays an interactive mock-up of the future form. Hovering over any component opens a quick actions panel:
    • Settings: opens a dialog with validation, API key and hint parameters.
    • Copy: clones the field together with all of its nested rules.
    • Paste below: inserts a previously copied component.
    • JSON: direct editing of the field schema (available in Advanced Mode).
    • Move: manually reposition the component elsewhere on the canvas.
    • Delete: removes the component from the schema.
⚙️ Advanced Mode

Enabled in the "Settings" section. Lets experienced developers configure custom calculation formulas, JSONLogic, PDF integration and edit component schemas as raw JSON. Detailed guide.

The "Publication Design" Section Screen

Controls the look and feel of the web pages shown to respondents.

Customization Options

  • Ready-made templates (assets): quickly attach a corporate header, footer or inactivity screen from the centralized asset catalog.
  • Code editor (Ace Editor): a built-in editor with HTML/CSS syntax highlighting for writing your own markup.
  • Live preview panel (Preview Box): renders the markup in real time as you type.
  • Theme styling: supports the light theme (Corporate Light) and the high-contrast dark theme (Dark Enterprise).

Embedding a form on another website

A publication can be embedded as a frame on an external website — for example, a corporate portal — so respondents fill in the form without leaving the site they already use.

  1. On the "Design" tab, enable the "Allow embedding this form on external websites" switch in the "Embedding" card.
  2. Specify the allowed origins — one per line, in the format https://www.ktz.kz. The form can only be embedded on a site whose origin is on this list (protection against embedding on arbitrary resources via CSP frame-ancestors), up to 10 origins.
  3. Click "Save design" — the setting takes effect within a few seconds.
  4. Copy the ready-made embed code with the "Copy code" button and hand it to the site owner. The code contains the frame and an automatic height-resize script.

Nothing else is required on the host side: the developer simply pastes the received code into the page — no keys, tokens or registration. A hand-written iframe pointing at the form URL will also work, but without the snippet's script the height has to be fixed. Keep the order in mind: the site's origin must be added to the list before the code goes live on their side, otherwise the browser will block the frame.

Limitations:

  • Role-based forms can be embedded too: a "Sign in" button appears inside the frame; sign-in opens in a separate window (the branded single sign-on page), and the form loads automatically afterwards — the host page is not reloaded.
  • Forms with mandatory signing (NCALayer) may not reach the signing application from a frame due to browser restrictions (Private Network Access). In that case the form itself offers to "Open in a new tab" — signing works in a separate tab. Test on the target site.
  • If the switch is on but the origin list is empty, embedding is denied — the form remains protected from being framed.

The "Translations" Section (Localization) Screen

Provides multilingual surveys for Russian-speaking, Kazakh-speaking and international audiences.

How Localization Works

  1. When you open the tab, the system automatically parses the current form schema and finds all text strings: field labels, placeholders, descriptions and error texts.
  2. An interactive table shows columns per language: Russian (RU), Kazakh (KK) and English (EN).
  3. CSV export: you can export the table to a file to hand over to professional translators.
  4. When filling in the survey, the respondent picks a language in the switcher and every question of the form is translated instantly without a page reload.

The "Dictionaries (Reference Data)" Section Screen

Centralized management of normative reference data: lists of departments, regions, categories and other values used in the dropdown lists of forms.

Registry and Editor

  • Dictionary registry: a table of all dictionaries with status, production version and last update date. A new dictionary is registered with the create button.
  • Built-in editor: spreadsheet-style record editing — add rows, live table search, double-click cell editing.
  • Import and export: bulk-load values from Excel/CSV, export the current draft to Excel, paste rows from the clipboard (Ctrl+C in Excel → click the table → Ctrl+V).
  • Draft and publishing: changes are stored with "Save draft"; "Publish" turns the draft into the production version that forms read their values from.
  • External dictionaries: rows with the cloud icon show the latest sync status; the lightning button triggers a manual sync.

External dictionaries (auto-sync)

A dictionary can receive its values from an external source automatically: the platform fetches the data server-to-server, maps it onto the dictionary contract and publishes a new production version — only if the data actually changed. A typical case is transport reference data maintained by an external ontology API (stations, train categories).

  • Configuration: the cloud button opens the source card — resource URL, transformer (field mapping), environment variable with credentials (Basic), update interval in minutes, on/off switch.
  • Manual sync: the lightning button in the registry row (or in the source card) runs an out-of-band update without waiting for the interval.
  • Sync log: the source card shows the log of recent attempts — time, status, HTTP code, records fetched and changed, published revision.
  • Revisions and consistency: every source change is recorded as a new immutable dictionary revision tagged with the external dataset version. Forms keep reading values even when the external source is unavailable — the last published revision is used. Manual editing of an external dictionary's draft is blocked: the next sync would overwrite it.
  • Rollback: instantly revert to any previous revision via the publication history, exactly like regular dictionaries.

Auto-fill fields by user (prefill)

Form fields can be filled automatically from the profile of the user who opened the form: the full name comes from the account (Keycloak), objects (sections, stations) come from personal assignments managed in the "Assignments" tab.

  • How it works: a form field carries the prefill property — when the form opens, the value is filled from the profile (the name is locked from editing), and dropdown options are filtered down to the objects assigned to the user.
  • Server-side guarantee: on submission the server validates the data independently of the browser — the name is always replaced with the account value, and the object choice is checked against the assignments. Tampering via DevTools is impossible.
  • If nothing is assigned: the object list stays full (fallback mode) and the user's choice is flagged as manual. Such values appear in the "Assignments" tab as candidates — once an administrator approves them, the fields fill automatically from the next submission on.
  • "Assignments" tab: manual grants (user lookup by email), the list of active assignments and candidates, approval and removal. Candidates are created automatically from submissions where the user picked an object manually.
🔐 External source credentials:

Basic credentials (user:password) are set per dictionary in the source card and stored in a protected table; they are never returned to the interface. Alternatively, an environment variable name can be specified — its value is then used for authentication.

💡 Attaching a dictionary to a form:

In a builder dropdown, set the data source type to "URL" and enter the dictionary address /api/v1/dictionaries/{code}. When the dictionary is updated, the form picks up the new values automatically — no form revision required. A step-by-step recipe is available in the Practical Scenarios section of the builder guide.

🔐 Access:

The tab is available to the admin and dictionary_manager roles — see the "Roles and Access Rights" card in the Security section.

The "Preview" Section Screen

An interactive environment for verifying the finished survey before publication.

The screen renders an exact copy of the live respondent interface with all connected styles, fonts, header and footer. It lets you test form submission, required fields, phone masks, file attachments and the question branching logic.

The "Reporting & Analytics" Section Screen

Tools for visualizing data and exporting collected responses.

Analytics Features

  • Real-time counters: the total number of submitted surveys (submissions) and the date of the last response.
  • "Response dynamics" chart: a timeline of survey completion by day.
  • Geographic response map: an interactive map of Kazakhstan with clustering of survey submission points (for forms that collect geolocation).
  • Per-field breakdown: select one or more questions from the dropdown — the system automatically builds pie and bar charts of the answer distribution.
  • Asynchronous Excel export (XLSX): when you press "Download Excel", the job is handed to RabbitMQ workers. The finished report downloads instantly without blocking the interface.

The "System Settings" Section Screen

Security, antivirus and platform maintenance parameters.

System Parameters

  • Maximum upload size: the size limit (in MB) for files allowed to be attached in forms.
  • Platform time zone: defines correct timestamp calculation in analytics and Excel exports.
  • Form translation languages: controls the languages available on the "Translations" tab and in published forms. Russian remains the primary language; Kazakh, Kyrgyz, English and Uzbek can be switched on and off.
  • Antivirus scanner (ClamAV): enables file scanning for viruses and defines the service address.
  • Keycloak roles mapping: maps platform system roles (Admin, Creator, Viewer) to Keycloak tokens.
  • Diagnostics bundle: builds a single archive with microservice logs, RabbitMQ queue states and the DLQ error queue for fast technical support.

"System Health" Panel

The "Maintenance" section shows live infrastructure metrics. The panel refreshes via the "Refresh" button and every time the tab is opened. How to read the metrics:

MetricNormal state and warning signs
Working queues (form_submissions, templates.v1, publications.modular, reports.tasks, files.quarantine)Depth of 0 is normal (growth by a few messages for seconds is acceptable under peak load). There must be ≥ 1 consumer. Alarm: depth keeps growing or consumers are 0 — the handler has crashed or the database is unavailable.
Retry queues (submissions_retry_queue and similar)Depth 0 when idle; a few messages is normal (delayed retries). 0 consumers is normal: this is a parking lot with a timer — the broker itself reads them on timeout.
Error queues (DLQ) (dead_letter_queue, webhooks.failed, reports.failed)Normal is exactly 0. Any value above zero is a signal to investigate: the DLQ does not drain itself. Rows are highlighted in red.
RabbitMQ / Database / RedisA green mark means the component is available. A red cross means the service is unavailable; hovering shows the reason.
Submissions per hour / per 24 hoursShould match the expected traffic. Zero under active traffic is a critical sign: responses from respondents are not being saved.
Idempotency recordsMonotonic growth is normal (duplicate protection). Tens of thousands of records without cleanup slow down processing — a question for the database administrator.
Active webhook subscriptionsHow many subscriptions are actually receiving events. Zero — events are not being delivered anywhere (check the "Integrations" tab). A subscription with constantly failing delivery accumulates errors in webhooks.failed.
💡 Quick rule

Working queues: 0 is good, consumers are mandatory. Retry: zero and zero consumers is normal. DLQ: zero only. If the submission counter is stuck at zero while people are filling in forms — check the savetodb logs immediately.

API Keys (M2M Integration & GraphQL) Integrations

Synchronous access for external BI/ETL systems (Power BI, Tableau, corporate CRMs) to analytics and exports without an interactive login through Keycloak.

API Token Security

  • whsec_ prefix: the token is generated by a cryptographically secure generator and shown only once at creation.
  • SHA-256 hashing: only the token hash is stored in the platform database. Even if the database is compromised, the original key cannot be recovered.
  • Visibility scope: a key can be global or restricted to selected publications only.

Sample GraphQL Request via cURL

curl -X POST https://suraqhub.domain.com/graphql \
  -H "Content-Type: application/json" \
  -H "X-API-Key: whsec_your_secret_api_key_here" \
  -d '{
    "query": "query GetPubStats($id: UUID!) { publicationStats(publicationId: $id) { totalSubmissions lastSubmissionDate } }",
    "variables": { "id": "16a5ff0e-f1ff-4b8a-9887-c5f907912ea1" }
  }'

Real-Time Webhooks Real-Time

Asynchronous delivery of HTTP POST notifications to your servers when events occur in SuraqHub.

Event Types:

  • submission.created — a user has filled in and successfully submitted the form.
  • form.saved — the question structure of the form has been changed or saved.
  • publication.saved — the publication has been changed or activated.

JSON Payload Specification:

{
  "event": "submission.created",
  "event_id": "9f1c2d3e-4b5a-6c7d-8e9f-0a1b2c3d4e5f",
  "timestamp": "2026-09-02T15:30:00.000Z",
  "publication_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "form_id": "f5e4d3c2-b1a0-9876-5432-10fedcba9876",
  "submission_id": "77aa88bb-99cc-00dd-11ee-22ff33aa44bb",
  "data": {
    "fullName": "Alexey Smirnov",
    "phoneNumber": "+77015554433",
    "score": 5,
    "comment": "Great performance!"
  }
}

Verifying the HMAC-SHA256 Signature (the X-SuraqHub-Signature Header)

Every request is signed with your subscription secret. The receiving server must verify the signature before processing:

Python Example (FastAPI / Flask):

import hmac, hashlib
from fastapi import FastAPI, Request, HTTPException, Header

app = FastAPI()
WEBHOOK_SECRET = "whsec_your_secret_key"

@app.post("/webhook")
async def receive_webhook(request: Request, x_suraqhub_signature: str = Header(None)):
    raw_body = await request.body()
    expected = hmac.new(WEBHOOK_SECRET.encode("utf-8"), raw_body, hashlib.sha256).hexdigest()

    if not x_suraqhub_signature or not hmac.compare_digest(expected, x_suraqhub_signature):
        raise HTTPException(status_code=403, detail="Invalid HMAC signature")

    payload = await request.json()
    print(f"✅ Event received successfully: {payload['event']}")
    return {"status": "ok"}

Reliability Guarantees (SRE Retry Policy):

  • Manual ACK: the message is acknowledged in RabbitMQ only after your server returns HTTP 200 OK.
  • Exponential Retry: on a network error or a 5xx code, the platform retries delivery up to 5 times with a growing interval.
  • Dead Letter Queue (DLQ): on fatal errors (404, 403) the message is safely stored in the suraqhub.webhooks.failed dead-letter queue for manual analysis.

Analytics for BI (the analytics Schema) Pull / BI

Connect Power BI (or any tool with a PostgreSQL connector) directly to a dedicated read-only database schema to build dashboards and reports over the accumulated surveys.

How This Channel Differs from Webhooks and API Keys:

  • Webhooks — instant push notifications for automation systems (reaction to an event within seconds).
  • API keys — synchronous queries to the GraphQL API for external services (data of a specific survey, business logic).
  • The analytics schema — history for humans: dashboards, funnels and aggregated reports in Power BI refreshed on a schedule.

Data Model:

  • vw_submissions — survey headers: when, which publication, language, signature presence. No response content.
  • vw_submission_answers — responses in a "long" format (one row = one answer). Universal for any form: in Power BI it is unfolded into a wide table with a Pivot.
  • vw_submission_geo — device coordinates (latitude, longitude, accuracy) for forms that collect geolocation.
  • vw_publications — publication directory: titles, submission policies, signature and geolocation, activity periods.

Security and Privacy:

  • Connection uses the dedicated read-only powerbi_reader role, which has access only to the analytics schema. Platform service tables (API keys, subscriptions, audit) are not accessible to the role.
  • No personal data is exposed: IIN, cryptographic signatures and raw metadata are not included in the views.
  • Writing is impossible by design — the role has read-only rights.

Connection:

In Power BI Desktop: Get Data → PostgreSQL, enter the server address and the suraqhub database, authorize under the powerbi_reader account (issued by the platform administrator). For published dashboards, add the same source to an on-premises Data Gateway.

Recommendation: use Import mode and configure scheduled refresh (for example, hourly or nightly) — heavy dashboards should not poll the database more often than necessary.

For high-load deployments the platform provides a read-only database replica: an administrator can point analytical reports and BI connections at the database copy (DATABASE_RO_URL), leaving the primary database for survey intake only. See suraqhub-docs/analytics_powerbi.md for details.

Downloading Files and Media (FileConductor API) File API

Secure programmatic and user-facing download of attachments (photos, videos, scans) uploaded by respondents in forms.

1. How Files Are Passed to External Systems

When the submission.created webhook is received or reports are exported to Excel/CSV, attachments are represented as an array of objects inside submission_data:

{
  "event": "submission.created",
  "submission_id": "123e4567-e89b-12d3-a456-426614174000",
  "submission_data": {
    "media_field": [
      {
        "file_id": "c0378e90-f99a-4c28-bb8d-d602ff59187a",
        "originalName": "photo_bridge.jpg",
        "size": 2450123,
        "type": "image/jpeg",
        "url": "/api/files/download/c0378e90-f99a-4c28-bb8d-d602ff59187a"
      }
    ]
  }
}

Each file is identified by a permanent UUID (file_id) and carries a relative URL for downloading.

2. Authentication Methods

The /api/files/download/{file_id} endpoint is protected and supports the following authorization methods:

  • M2M API key (recommended for scripts/ETL): passed in the X-API-Key: whsec_... header or the ?api_key=whsec_... URL parameter. Keys are created in the "Integrations" tab of the manager.
  • Keycloak Bearer JWT (for internal services): passed in the Authorization: Bearer <token> header or the ?token=<token> parameter.

3. Download Modes

A. Direct redirect (HTTP 302) — for browsers and utilities

When the ?redirect=true parameter is passed (or when navigating from a browser), the FileConductor gateway instantly redirects the client (HTTP 302) to an S3 Presigned URL with the correct Content-Disposition header. The file downloads immediately with its original name (for example, photo_bridge.jpg):

# Download via cURL preserving the original name:
curl -L -O -J -H "X-API-Key: whsec_your_key_here" \
  "https://suraqhub.dostyq.app/api/files/download/c0378e90-f99a-4c28-bb8d-d602ff59187a?redirect=true"

B. JSON mode (default) — for two-step integration

Without the redirect=true flag, the endpoint returns JSON with metadata and a temporary signed S3 link (15 minutes lifetime):

GET /api/files/download/c0378e90-f99a-4c28-bb8d-d602ff59187a
X-API-Key: whsec_your_key_here

Response:
{
  "status": "success",
  "file_id": "c0378e90-f99a-4c28-bb8d-d602ff59187a",
  "filename": "photo_bridge.jpg",
  "download_url": "https://s3.ktz.dostyq.app/suraqhub-clean/c0378e90-...?X-Amz-Signature=..."
}

4. Integration Examples

Python (requests / httpx)

import requests

FILE_URL = "https://suraqhub.dostyq.app/api/files/download/c0378e90-f99a-4c28-bb8d-d602ff59187a"
HEADERS = {"X-API-Key": "whsec_your_secret_api_key"}

# Option 1: Direct download with redirect
response = requests.get(f"{FILE_URL}?redirect=true", headers=HEADERS, stream=True)
if response.status_code == 200:
    with open("downloaded_media.jpg", "wb") as f:
        for chunk in response.iter_content(chunk_size=8192):
            f.write(chunk)
    print("✅ File saved successfully!")

# Option 2: Fetch metadata and the presigned URL
meta_resp = requests.get(FILE_URL, headers=HEADERS).json()
print("Filename:", meta_resp["filename"])
print("S3 link:", meta_resp["download_url"])

Node.js / JavaScript (fetch)

const fs = require('fs');
const { pipeline } = require('stream/promises');

async function downloadFile(fileId, apiKey) {
  const url = `https://suraqhub.dostyq.app/api/files/download/${fileId}?redirect=true`;
  const res = await fetch(url, {
    headers: { 'X-API-Key': apiKey }
  });

  if (!res.ok) throw new Error(`Download failed: ${res.statusText}`);
  await pipeline(res.body, fs.createWriteStream('downloaded_media.jpg'));
  console.log('✅ File downloaded successfully');
}
🛡️ Security Policies and the suraqhub_downloader Role
  • Keycloak role: the system has a dedicated suraqhub_downloader role (Right to download files and media attachments). You can assign it to trusted employees or a service account of an external system and select it in "System Settings". Administrators (suraqhub_admin) always have download access.
  • Antivirus quarantine: a file cannot be downloaded until the ClamAV service assigns it the CLEAN status. Attempting to download an infected file returns a 403 Forbidden error.
  • Access management: in "System Settings" the administrator can enable/disable downloads via M2M API keys and select the required role.

Exporting Reports to Your Own S3 Storage Storage

Ability to store generated reports directly in a corporate AWS S3, MinIO or Ceph bucket.

🔒 End-to-End Fernet Encryption

Your S3 credentials (Access Key, Secret Key) are encrypted on the fly with the Fernet algorithm when the createReport GraphQL mutation is called, and are decrypted exclusively inside the isolated background worker.

Security, ClamAV and Accessibility Security

🛡 ClamAV Antivirus Barrier

User files are not stored directly in a shared file system. They pass automatic scanning through an isolated ClamAV daemon. Infected files are blocked before they can reach operators or exports.

🔐 Content Security Policy (CSP)

The SuraqHub interface is designed to a strict CSP standard: unsafe-inline scripts are excluded, all events are moved into modular listeners, preventing XSS attacks and session theft.

♿ Interface Accessibility (WCAG 2.2 AA)

Forms are fully accessible to people with disabilities: keyboard navigation, semantic WAI-ARIA attributes (aria-live, role="region"), screen readers and high-contrast color palettes are supported.

👥 Roles and Access Rights

Roles are assigned by an administrator in the Keycloak Admin Console; inside the platform there is a read-only user overview:

  • admin — full access: system settings, integrations, dictionaries, all publications and reports;
  • creator — creating forms and working only with their own publications and the reporting for them;
  • dictionary_manager — maintaining dictionaries (reference data) without creator rights;
  • suraqhub_downloader — the right to download files and media attachments via the File API (see File Downloads).

In addition, every publication has an access level: Public (open to everyone via the link) or Role Based (access only for users with selected Keycloak roles). Periodic reporting is available only in the Role Based mode.

Frequently Asked Questions (FAQ) Knowledge Base

How do I change the form address after publication?
Change the value of the "URL (Address)" field on the "General" screen and press "Save publication". Note that the old link will stop working, so send respondents the updated address.
What happens to old responses when the form questions are edited?
All previously collected responses are preserved in the database in their original form. Editing creates a new form revision. In the Excel export, responses appear with all the fields they had at the moment of submission.
Why is the Excel export generated asynchronously?
Asynchronous processing through RabbitMQ guarantees that even when exporting 500,000+ responses with files, the web server will not time out and the user interface stays fast and responsive.
How do I restore a previous version of a form if the new one was saved with an error?
On the "General" screen, in the "Revision history" block, find the required date/time and click the entry. The system will restore that revision's schema in the builder. After verifying it, press "Save form".
What should I do if a webhook does not reach an external system?
1. Check that your URL endpoint is reachable from the cluster network.
2. Make sure your server returns HTTP 200 OK.
3. Verify that validation of the X-SuraqHub-Signature signature uses your subscription secret.
4. Download the diagnostics bundle on the "Settings" screen to analyze the suraqhub.webhooks.failed queue.

Periodic Reporting

"Submission settings" allow enabling daily, weekly or monthly reporting. This setting is available only for publications with Role Based access.

  • Continue current report: when reopened within the same period, the last submission is shown; a new submission is saved as a separate version.
  • Once: only one submission per period is allowed.
  • Refill: every submission is independent.

The initial data of a new period can be left empty or copied from the previous period. This setting applies only when the form is first opened in a new period. Developer details: docs/periodic-reporting.md.