Formerly FormRelay. Ackvia is the continuation and expansion of the original FormRelay project.
Lead reliability infrastructure for agencies.
Formerly FormRelay. The project was renamed to Ackvia as its scope expanded beyond basic form-to-Telegram delivery.
Ackvia is an actively developed backend platform for capturing and reliably delivering leads generated by websites.
The project started as a headless form backend: create an endpoint, connect an HTML form, store the submission in PostgreSQL, and forward it to Telegram. It is now evolving toward a broader Lead Reliability / LeadOps platform designed to give agencies visibility into whether leads were captured, persisted, delivered, or lost somewhere downstream.
The current release implements the original form-processing workflow. Delivery tracking, recovery, monitoring, and agency-level operations are the next stages of development.
Hosted MVP: https://formrelay-5ysr.onrender.com Frontend: https://ackvia.vercel.app
The hosted URL still use the former FormRelay name during the transition to Ackvia.
A website being online does not mean its lead path is healthy.
A submission can be accepted by the frontend while email, Telegram, a webhook, CRM integration, or another downstream service fails separately. When several client websites use different delivery mechanisms, diagnosing these failures becomes fragmented.
Ackvia is being built around a simple requirement:
A captured lead should have a traceable lifecycle from submission to destination.
The long-term model is:
Website
│
▼
Lead captured
│
▼
Persisted
│
├──► Destination A ── delivered
├──► Destination B ── retrying
└──► Destination C ── failed
│
▼
Incident
Forms are the first lead source. The architecture is intended to grow beyond them without turning Ackvia into a general-purpose CRM.
The current implementation provides a complete basic form-processing flow:
HTML / JSON form
│
▼
FastAPI endpoint
│
▼
Validation
│
▼
PostgreSQL
│
▼
Telegram notification
- UUID-based form endpoints
- JSON submissions
- Standard HTML form submissions
- Multipart text fields
- Asynchronous PostgreSQL access
- Structured submission storage
- Telegram notifications
- HTML-safe notification formatting
- Browser redirects after HTML submissions
- JSON API responses
- English, Ukrainian, and German localization
- Docker configuration
- Automated flow tests
- Ruff linting and formatting
- GitHub Actions CI
- Render deployment configuration
Ackvia currently persists a submission before attempting Telegram delivery.
This distinction is intentional:
HTTP request accepted
↓
submission stored in PostgreSQL
↓
Telegram delivery attempted
A successful HTTP response therefore confirms that the submission handler completed, but it does not yet provide a durable guarantee that Telegram received the notification.
Failed Telegram requests are logged.
Persistent delivery states, retries, replay, and incident tracking are planned as part of the Lead Assurance architecture.
Open the hosted MVP and create a form endpoint.
Then use the generated UUID as the form destination:
<form action="https://formrelay-5ysr.onrender.com/f/YOUR_FORM_ID" method="post">
<label>
Name
<input name="name" required>
</label>
<label>
Email
<input name="email" type="email" required>
</label>
<label>
Message
<textarea name="message" required></textarea>
</label>
<button type="submit">Send</button>
</form>Field names are flexible. Ackvia does not require a predefined contact-form schema.
Browser-side validation such as required improves the user experience but does not replace server-side validation.
| Method | Path | Purpose |
|---|---|---|
POST |
/api/forms |
Create a form endpoint |
POST |
/f/{form_id} |
Submit data to an existing form |
GET |
/ |
Open the setup interface |
GET |
/success |
Open the default success page |
curl -X POST http://127.0.0.1:8000/api/forms \
-H 'Content-Type: application/json' \
-d '{
"title": "Portfolio",
"telegram_chat_id": 123456789,
"language": "en"
}'The response contains the generated form UUID.
curl -X POST http://127.0.0.1:8000/f/YOUR_FORM_ID \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
"name": "Alex",
"email": "alex@example.com",
"message": "Project enquiry"
}'When JSON is requested, the endpoint returns the submission status and submission ID.
A regular browser form submission is redirected to the success page.
- Python 3.12+
- uv
- Docker with Compose
- PostgreSQL
- Telegram bot token
Clone the repository:
git clone https://github.com/loppify/Ackvia.git
cd Ackvia
uv syncCreate .env in the repository root:
DATABASE_URL=postgresql+asyncpg://postgres:password@localhost:5432/formrelay
TELEGRAM_BOT_TOKEN=replace_with_your_bot_token
BASE_URL=http://127.0.0.1:8000Start PostgreSQL:
docker compose up -d dbStart Ackvia:
uv run uvicorn app.main:app --reloadThe application is then available at:
http://127.0.0.1:8000
Run the test suite:
uv run pytestRun linting:
uv run ruff check .Check formatting:
uv run ruff format --check .The current flow tests use an in-memory SQLite database and mock Telegram delivery.
They cover:
- form creation
- JSON submission
- HTML form submission and redirect
- unknown form IDs
- notification flow without contacting Telegram during tests
These tests verify application behavior but do not currently establish production PostgreSQL behavior or resilience during real downstream failures.
app/
├── api/ form creation and submission routes
├── core/ configuration and localization
├── database/ SQLAlchemy models and async sessions
├── services/ external delivery services
├── static/ frontend assets
├── templates/ server-rendered pages
└── translations/ UI and notification translations
tests/
└── automated flow tests
Ackvia is moving from form processing toward lead assurance.
The current development focus is establishing a reliable lead lifecycle:
- explicit delivery states
- delivery-attempt history
- transient-failure retries
- manual replay
- destination verification
- stronger payload boundaries
- rate limiting
- spam and abuse protection
- database migrations
- incident visibility
The intended lifecycle is:
received
↓
persisted
↓
delivery pending
↓
delivered
or, when something goes wrong:
received
↓
persisted
↓
delivery failed
↓
retrying
↓
recovered / failed
After the reliability foundation, Ackvia is designed to expand toward managing lead infrastructure across multiple client websites:
- agency workspaces
- clients and websites
- multiple lead destinations
- portfolio health
- centralized incident history
- delivery routing
- client-facing reliability evidence
- additional lead sources
Potential later stages include:
Lead Assurance
↓
Agency LeadOps
↓
Response SLA
↓
Attribution
↓
Revenue Intelligence
These stages are product direction rather than implemented functionality.
Ackvia is not intended to become a generic CRM. Its focus is the infrastructure and operational layer around leads before and between the systems that ultimately manage them.
The current MVP intentionally has a limited scope.
Not yet implemented:
- durable delivery-status tracking
- automatic delivery retries
- manual replay
- destination ownership verification
- advanced spam protection
- application-level rate limiting
- file uploads
- agency accounts and workspaces
- client management
- portfolio monitoring
- CRM integrations
- billing
- configurable retention
- production migration history
Alembic is included as a dependency, but the current application still creates missing tables using SQLAlchemy startup logic rather than maintaining a full migration history.
Backend
- Python
- FastAPI
- Pydantic
- SQLAlchemy
- asyncpg
- HTTPX
Data
- PostgreSQL
- JSONB
Quality and infrastructure
- pytest
- Ruff
- Docker
- Docker Compose
- GitHub Actions
- Render
Ackvia is an ongoing personal software engineering project.
The current public version is functional, but the project is actively being redesigned around stronger reliability guarantees, delivery observability, and multi-client lead operations.
The repository therefore contains both a usable MVP and an evolving production-oriented architecture.
Ackvia was originally developed and published as FormRelay.
The former name may still appear in:
- older CVs and job applications
- deployment URLs
- commit history
- configuration names
They refer to the same project.
New product documentation and development use the Ackvia name.
GNU Affero General Public License v3.0.