From the team behind aidrop.it — one workspace to build, host, and keep changing your code.
A lead form needs three things to work: a page that accepts a request, an API that validates it, and a database that keeps it after deployment. Build those as one FastAPI web service backed by PostgreSQL. The decisive test is submitting a record, redeploying the application, and finding that same record afterward.
Use a coding agent with a shell and Git, connect it through the quickstart, and choose an aidrop.it Project with capacity for an application and PostgreSQL. Start with synthetic test details. Collect real customer information after you have checked access, abuse controls, and the recovery procedure.
1. Define the smallest useful form
Serve the form and its API from the same application. Ask for a name, email address, and short message; validate every field on the server. Return a confirmation only after the database transaction commits, so a success message means the record was saved rather than merely received by the web process.
Use GET / for the page, POST /leads for submissions, and GET /health for a lightweight health check. Set field length and request size limits. Keep the saved records behind an authenticated owner view or inspect them privately through a database client; do not expose a public endpoint listing leads.
For owner notifications, the deployed-app email check covers a verified sender, runtime network access and a notification record that survives a release.
Ask the agent for a schema migration that creates a leads table with an ID, the three fields, and a creation timestamp. Keep migration files in Git. Your app has nowhere to write explains why a JSON file or local SQLite database is the wrong storage path for this runtime.
2. Attach PostgreSQL and pass its connection string
Create or reuse a database in the same Project, attach it to the application, and provide its connection string as a runtime secret. These are separate operations. Network access alone does not configure the application, and storing a connection string alone does not attach the managed database to its Service.
Have the agent call shared_resources_list first. If PostgreSQL already runs in this Project, it can create a separate database inside that instance. If a new instance is needed, the tool requires your explicit confirmation and a plan that supports it. The returned connection string belongs in DATABASE_URL through project_secret_set.
For a new application, first deploy a bootstrap revision that serves only /health, with no form or database requirement. That creates the Service ID needed for attachment. Attach the database with shared_resource_update, store the returned URL, and make the full application's next build require DATABASE_URL. Keep credentials out of Git and logs.
The Django deployment walkthrough applies the same database attachment flow to an app with migrations and an authenticated admin.
3. Deploy the application and run its migration
Build the application from a Dockerfile with an explicit Python version and locked dependencies. Start one server process on the configured port. Make the initial migration a deliberate part of this small deployment, and fail startup if it cannot complete; an application accepting submissions against a missing table is not ready.
The FastAPI container guide explains building your own image and running the server inside it. For this single-process example, an entrypoint can run alembic upgrade head and then start Uvicorn on 0.0.0.0 using the runtime's PORT. Do not use development reload mode.
Push the full revision and call service_build on the existing Service with:
{
"build_type": "dockerfile",
"build_dockerfile_path": "Dockerfile",
"runtime_kind": "python_http",
"container_port": 8000,
"health_path": "/health",
"required_secret_names": ["DATABASE_URL"]
}
Poll service_get, inspect any failed stage through service_logs, then open the form at the public URL. Verify the migration and submit a test lead. Check that the migration actually landed covers the database check. Larger deployments need migration coordination; do not have several replicas independently apply schema changes.
Copy this build and verification brief
Use this brief to keep the first deployment focused on one complete user action. The test record must remain identifiable after a second deployment, and invalid submissions must fail without creating rows. Keep the resulting verification record in the repository, with test identifiers rather than customer details or database credentials.
Build a lead form using FastAPI and PostgreSQL in Project <project>.
Serve GET /, POST /leads, and GET /health from one application.
Validate name, email, and message; enforce input size limits.
Save with parameterized queries and confirm only after commit.
Create a versioned migration for a leads table.
Keep records private; do not add a public lead-list endpoint.
Use DATABASE_URL from runtime secrets; never print its value.
Inspect existing Project resources before requesting a new database.
If needed, deploy a health-only bootstrap to obtain the Service ID.
Attach PostgreSQL, store its URL, then deploy the complete app.
Use a Dockerfile, port 8000, /health, and one server process.
Run the migration before accepting traffic; fail if it fails.
Report the commit, URL, migration revision, and checks performed.
VERIFY BEFORE SHARING
[ ] A valid synthetic submission creates one row.
[ ] Invalid or oversized input is rejected without inserting a row.
[ ] A database failure cannot produce a success confirmation.
[ ] Existing test data survives a second application deployment.
[ ] Visitors cannot list or read other submissions.
[ ] Logs contain neither credentials nor submitted personal details.
[ ] Abuse controls and a tested database export/restore are in place
before collecting real leads.
FAQ
Can I run the form and API as one Service? Yes. FastAPI can serve the page and process its submissions. A separate frontend deployment is optional for this small application.
Does aidrop.it store the database URL automatically? No. The managed resource operation returns a connection string. Store it as a Project secret and include its name in the Service's required_secret_names before the next build.
Will rolling back the application undo the migration? No. Treat code rollback and database recovery separately. Make schema changes compatible with the previous application revision, and test your own database export and restore procedure.
Get it running from the session you are already in
Connect your coding agent over MCP and ask it to deploy. aidrop builds the repository and runs it on a public address; when a build or the app fails, the log says why, and your agent fixes it and builds again.