Skip to content
THE PATH FROM YOUR AGENT TO A RUNNING APP

One project
From code to a URL

Connect your code, build it and confirm a deployment. Here is what happens along the way, what you control and what your application needs.

In short

What actually happens, in five steps

No vocabulary needed for this part. Each step links to the section that explains it, and the words the rest of the document uses are defined immediately below.

  1. You bring code, or start from a template

    An application that already runs on your machine, or nothing yet.

  2. It is built, and a failure says why

    What stopped the build is named - a missing start command, a value the code needs, a port nothing listens on - with the log that says it.

  3. It gets an address

    Built, deployed, answering - and open to the internet from that first deploy, which is worth knowing before you push.

  4. What was done stays

    The repository, every build and its log, the address, the values and who may reach them live with the project rather than in the session that produced them.

  5. The next agent starts from there

    Any assistant your team has authorised reaches this project and the team's other projects, and nothing outside the team.

That is the whole of it. The rest of this document is how each step is built, and what it refuses to do. Or you can connect your agent and try it against a repository you already have.

The practical flow above is enough to get started. The technical reference below covers the architecture, what a project runs on, and where the hosting stops.
TL;DR

aidrop keeps a repository, where it runs, every build that got it there and who may reach it, in one record called a Project. An agent connects to your Team and reaches those records, and nothing outside them.

It does not write your code. Your developer or your agent does that, and the repository stays where it already is. What aidrop adds is the operable part - the thing that runs, the address it answers on, and the record of how it got there - so it survives the session that produced it.

Everything below is a mechanism, not a policy. Where a boundary holds, it holds because of how the system is shaped - and where something is not built or not promised, that is said too.

Glossary

The words the rest of it uses

11 terms carry the document. They are used precisely and they are not interchangeable, so they are worth two minutes - but not before you know what happens, which is why they are folded and why the steps above needed none of them.

Show the 11 terms
Team
The tenant. Every person belongs to exactly one, and everything - Projects, billing, access - hangs off it.
Project
The durable unit, and the entity that holds services. One record - a repository, who may reach it, its delivery state and its history - together with what runs for it: the application services and the backing services they link. It is what a plan counts and what an address answers for.
Service
The smallest thing that runs: one container, with a size class, a network membership and a log of its own. Nothing smaller is deployed, sized, stopped or reserved. A Project's application is a service; each backing service - a database, a cache, a queue - is another, owned by that same Project and reached by the Services in it that link to it.
Project Takeover
Bringing software that already exists under that record: the repository connected, an owner named, and the first build run so that what does not work here is named by a build rather than guessed at.
Connected app
An agent your Team has authorised over OAuth. It holds read or write on your Team's Services, it is listed in the dashboard, and any admin can revoke it there.
Template
A runtime contract for one way of serving traffic - the kind, the port, the health endpoint - and the Dockerfile scaffold that goes with it.
Backing service
A server aidrop runs beside your applications and hands them a connection string for - a database, a cache, a queue. It belongs to one Project, which runs at most one of each kind, and every Service in that Project can link to it. It is never a Project of its own.
Runtime value
One named string a Project's application reads from its environment. Written by your agent, or written for you when you link a backing service. Never returned once stored, by any surface, to anybody.
Runtime contract
What the platform needs in order to run the code: runtime kind, container port, health endpoint and resource class. Recorded on the first build and copied into the deployment.
Managed Runtime
Where a Project's application runs when aidrop hosts it. A cluster is enrolled; the control plane reaches it over one HTTPS address with one token.
MCP
The protocol an agent speaks to reach a Project, and the only one. There is no public REST API.
Vocabulary

Four names for one thing

The product is described at four levels and they are not interchangeable. Collapsing them into one feature list is how this gets explained badly - a customer hears a memory tool bolted to a hosting provider, which is a fair reading of a feature list and a wrong reading of the product.

Software Continuity - the outcome

Software stays understandable and operable after the person, team or session that built it is gone.

Project Takeover - how you arrive

Existing software is brought under control: the repository connected, an owner named, and a first build run - because a build is the only thing that can say whether a revision runs here.

Project Workspace - the durable object

One record holding the repository, what runs from it, the address it answers on, the values it reads and who may reach them.

Project Control Plane - the architecture

The systems that govern that record. Internal language; you will not meet it in the product.

Those are the words. The next two pages are the shape they describe - first from outside, where only the callers and the dependencies are visible, then from inside.

Diagram C1

The system, from outside

Three kinds of caller reach aidrop: an agent over MCP, a person over a signed-in session, and - from the first deploy onward - anyone who has the address. They arrive at one control plane, which holds the Project record, decides access and drives delivery.

Your AI agentClaude Code, Cursor, CodexYour teama signed-in dashboard sessionAnyone with the addressa visitor at a deployed applicationaidrop control planeholds the Project record · decides access · drives deliveryYour codeGitHub, or your Team's GitA runtime clusterone HTTPS address, one tokenBillingthe payment provider
C1. Your repository and the machine your application runs on are outside the product on purpose - that is the whole point of the drawing.

Open the middle box and it separates into two groups with a real boundary between them.

Diagram C2

The system, from inside

On the left, the processes that are ours. On the right, a machine that holds customer code. The control plane calls the cluster's own public address; the cluster calls nothing back.

CONTROL PLANERUNTIME CLUSTER - OUTSIDE THE TRUST BOUNDARYAPI serverthe dashboard's own API and the webhooks; no public REST surfaceMCP serverthe tools an agent callsDatabase + object storagethe single source of truthBuilderclones, builds and pushes, in steps that hold different credentialsControllerthe only thing that can start or stop anything hereEdgeserves each project's addressEgress proxythe only way out for an application, and the record of itBacking servicesone of each kind per ProjectHTTPSone token
C2. One arrow, one direction. There is no shared network and no host-to-host trust: the cluster calls nothing back.

The database is the only source of truth, and there is no second store to fall out of step with it. There was one - a search index over everything a Team had written here - and it went with the part of the product that wrote it. Nothing derived is kept any more, which is a smaller system and one fewer thing to be wrong.

Every one of those separations is load-bearing. The next page says which, and what each refuses.

Security

Security: where the boundaries are

None of what follows is a policy. Each is a shape the system was built into, which is the only kind of boundary worth telling a customer about - a policy is a promise about future behaviour, a shape is a statement about present behaviour.

An agent reaches one Team, and you can see which

An agent authorises over OAuth against exactly one Team - the account picks it once, on the consent screen - and it holds read or write on that Team's Services and nothing wider. Every connected agent is listed in the dashboard with what it holds, and any admin can revoke one there. Be clear about the boundary this is: it is the Team, not one Project. An agent your Team has authorised reaches every Project in it.

Two edges, never one

The edge in front of aidrop and the edge in front of customer applications are separate instances, and the driver that creates customer routes is given only the customer edge's address. A bug in route provisioning can break a customer's address; it cannot rewrite ours.

Your code is handed no credential of ours

Platform cookies and tokens are stripped before a request reaches an application, and the build step that runs your repository is given none either. Nothing in the container was ever handed the means to act as aidrop - not withheld from it, never issued.

One way out, and it is recorded

A project's network reaches the internet through a proxy and nowhere else, so what an application talks to is a fact rather than an assumption.

Abuse is answered by closing the address

There is no review before an address opens - it opens on the first deploy. What exists is the other end: an address found to be serving something it should not is closed at the edge, which answers a notice rather than the application. That is enforcement against a Team, not a gate every customer passes through.

Your deployed app is public

Anyone can visit your app as soon as its first deployment starts serving. Aidrop does not require a separate publishing step or restrict who can visit the address. If your app needs sign-in, add it to your app before you deploy.

Your Team controls who can access the Project, including its repository, builds and delivery history. Those permissions do not limit who can visit the deployed app.

Boundaries decide what an agent may reach. What it should do once it is there is a separate question with a separate answer.

Templates

What a new project starts from

There is no catalogue to choose from, and that is a decision rather than a gap. A Service is a name, a description and an owner; what it is gets decided by the code you push to it. What the platform keeps is the small part it genuinely needs to know in order to run that code.

What a template actually is

A runtime contract for one way of serving traffic - the kind, the port to send requests to, the health endpoint - and the Dockerfile scaffold that goes with it. Four of them, plus the case where you bring your own.

RuntimePortHealthWhat it is for
Node (HTTP)3000/healthA server that answers HTTP. The shape most agent work ends up being.
Python (HTTP)8000/healthThe same, with a schema migration run beside it before the new version takes traffic.
Go (HTTP)8080/healthA compiled binary in a small image.
Static site8080/Files served by nginx. Port 8080 rather than 80, because the container drops the privilege that would be needed to bind 80.

A root Dockerfile is the fifth option, and the universal one

A repository with a Dockerfile at its root is built as-is and nothing is inferred about it. That is what makes Java, PHP, Ruby, Rust and .NET work here without any of them appearing in a list: the platform stops guessing and runs what you wrote.

What you are asked for instead of a template

Three answers, once, on the first build: the port your application listens on, the health path, and the size it runs at. They are copied into the deployment rather than looked up, so a later change to our defaults cannot move a running application underneath you.

Before that: what the thing actually runs on, and what it is allowed to keep.

Resources

Resources: what a project runs on

Two things are sized separately and it is worth keeping them apart. The application has an envelope - processor and memory - and the services behind it are their own instances, billed and scaled on their own terms.

What a project runs

Two words carry this section, and they are different sizes. A project is the entity: the record - a repository, who may reach it, its delivery state and its history - together with what runs for it. It is what a plan counts and what an address answers for.

A service is the smallest thing that runs: one container, with a size class, a network membership and a log of its own. Nothing smaller is deployed, sized, stopped or reserved. A project runs services - exactly one application, and the backing services it links: a database, a cache, a queue. A backing service belongs to the project that runs it - two projects never share one instance - and is reached through that project; it is never a project of its own.

However many services a project runs, it is still one project. A plan's count is a count of projects, not of the services they are assembled from, and archiving one gives its place back.

The distinction is worth keeping, because the two are counted by different things. The record fills a slot. What it runs spends the pot.

It was not always that way, and the way it went wrong is worth stating rather than quietly fixing: a service used to occupy a project slot of its own, so a plan priced a project by how many pieces it had been built out of. A tier held about half as many database-backed projects as the number on its card, and the customer met the difference as a refusal.

What the parts do spend is capacity. Every container a Team runs draws on one pot of processor and memory - applications and backing services alike - and the plan sets how big that pot is. So a project reserves the sum of its services:

ServiceWhat it reservesChosen by
The application0.5 vCPU · 512 MB and upYou, from the sizes your plan includes
Each backing service0.25 vCPU · 256 MB for a databaseA tuned default, or a size you pick from Pro
A second environmentThe same again, while it runsOnly when you deploy one

A shop on Pro is the arithmetic in full. Give it a compact application and the database behind it and the project reserves 1.25 vCPU and 1.25 GB. The plan holds 3 vCPU and 3 GB, so two of those fit and a third does not - which is where the number on the plan card comes from, rather than from a figure chosen to look generous.

Two consequences follow, and both are the kind a build meets late. The pot counts what is reserved, not what is busy: a stopped application keeps its share until the project is archived. And going past it refuses the next deployment rather than stopping what is already running - a limit that took a live application down to admit a new one would be the worse of the two failures.

What the application gets

Five envelopes, and they are copied into a profile rather than looked up, so a later policy change cannot quietly resize a workload somebody already reviewed.

ClassProcessorMemoryWhere it is available
micro0.5 vCPU512 MBIncluded with every plan that hosts anything.
compact1 vCPU1 GBShared node.
dual2 vCPU2 GBShared node.
medium2 vCPU4 GBScale and above.
large4 vCPU8 GBBusiness only - it is the whole of Scale's allowance.

The first three double cleanly on a shared node, where memory rather than processor decides how many projects fit. The last two need a bigger allowance than the tier below has in total - which is a boundary drawn by arithmetic rather than by a rule, and those are the boundaries that do not need defending when the numbers move.

Nothing here has a disk. An application runs on a read-only root with scratch space that does not survive a restart, so anything that must outlive one lives in a service.

That applies during startup as much as during ordinary work. A cache, a PID file or generated runtime configuration belongs in the bounded scratch paths the runtime names; a record belongs in the database or another backing service. An application must not use its own filesystem as a substitute for either. If a product needs durable uploads, media or a local index, it needs an external object-storage service: aidrop does not currently give application containers a data volume.

What a service can be

ServiceWhat it is forRead asAcross a restart
PostgreSQLThe durable one. Records that must survive a restart.DATABASE_URLKeeps its data
ValkeyA cache and a place for ephemeral state - sessions, rate counters, short-lived queues.CACHE_URLForgets, by design
Valkey queueWork handed off to be done later, so a slow job does not hold a request open. Refuses new work when full rather than dropping it.QUEUE_URLKeeps its volume

Only the cache is allowed to forget, and that is the whole reason it is a separate line rather than a setting. A database that forgets is not a database and a queue that drops its messages on a restart is not a queue, so both of those are given a volume. A cache is not, because giving it one would promise a durability nothing backs up.

The queue writes an append-only log to its volume once a second, so a restart costs at most the last second of accepted work - there is nothing to mark persistent and no durable-queue setting to get right, because it is the store that is durable rather than a property of each message. When it is full it refuses the write instead of dropping the oldest, so a producer finds out. We keep the store - what goes into it, and how, stays your code's decision.

An instance holds databases; a Service links to one

The instance is the billed unit - one of each kind per Project - and the Project creates as many databases inside it as it needs; the link from a Service to one of them is described above.

It sat one level higher until 2026-09-04, owned by the Team and shared between its Projects, and that is worth saying rather than quietly changing: a Team can be an agency, and two of its customers would have been sharing one database server. A Project is the boundary now.

The Project's PostgreSQL instanceone of each kind per Project - this is the billed unitshop_productiona database inside itcrm_productiona database inside itDATABASE_URLCRM_DATABASE_URLService: storefrontreads the name the link carriesService: adminreads the name the link carries
A Service links to a database, not to the instance, and the link carries the variable name the application will read. Two Services of the same Project can share one instance because the second one is not obliged to call its database DATABASE_URL - a name only one of them could have.

Deleting a service deletes its data with it. Have your agent take a copy first if you want one. The volume used to be kept and handed to the next instance of the same kind, which read as the safer default and was not: it left a database running under the previous instance's password, with no way to tell from the outside, and it held disk nobody could account for.

Backups are yours to make

We keep no backup copies and make no restore promise - a smaller offer than it could be, and a true one. What we do give you is the means: your agent can take a copy whenever you want one, and we keep none of it. There is no retention window to ask about because there is no retention.

Two ways, by size. For a small database the agent reads it directly with shared_database_query, the same call it uses to check that a migration landed - one statement at a time, 30 seconds and 64 KB per answer, so a copy is taken table by table, in pages. For a database of any size, the agent deploys a small Service inside the Project that runs pg_dump against the connection string it is handed and sends the file over HTTPS to storage you own - an S3 bucket, or wherever you keep copies. On a schedule, that is your backup policy. Nothing outside the Project can reach the instance, which is why the job runs inside it.

We delete services too, in two situations, and each has a clock. A Team whose plan stops covering hosting has its applications stopped after three days and its services kept for sixty: on the fiftieth day every admin is mailed that deletion is due, on the sixtieth the services and their data are deleted and the admins are told it happened. Choosing a plan with hosting before that day cancels it. A Team suspended for abuse is on a shorter clock with no mail: from the moment of suspension every address it serves answers 403 with a notice naming [email protected], its applications are stopped, and thirty days later its services are deleted unless the suspension is lifted. Paying does not lift a suspension; writing to support can. Both timelines are in the Terms, and the Project itself - its record and its repository - is not what either of them deletes.

Three builds, and what each of them asks for

BuildClassServicesWhy
A page and a formmicrononeNothing is kept between restarts, so there is nothing to attach.
A shop with a catalogue and orderscompactPostgreSQLRecords that must survive a restart go in the durable one; payment happens at the provider over HTTPS.
A product with accounts and model callsdualPostgreSQL · cache · queueSessions in the cache and slow work on the queue, so a model call does not hold a request open. Both start at Scale.

Which plan a build actually needs

The same question from the other side. A plan is a pot of capacity and a set of services, and the useful way to read one is not what it includes but where it runs out - because that is the line a build crosses without being told.

PlanBest forIn practiceWhere it stops
Starter$5/molanding pages and micrositesA personal page, a CV, a portfolio, a small brochure site, a blog whose posts live in the repository. Anything whose content is deployed rather than written by its visitors.The moment something must be saved. There is no database and no disk, so a contact form with nowhere to put the message, or a blog with an admin screen, is already the next plan.
Pro$20/mosmall apps and online storesA small shop with a catalogue and orders, a messenger bot that remembers its conversations, a background handler working through a table of jobs, an internal tool for a few people. Two projects, so a site and its admin can be separate deployments.At the point where slow work starts holding requests open. A database is included; a cache and a queue are not, so sessions and queued jobs live in tables until Scale - which works, and stops working under load.
Scale$99/moSaaS, CRM and ERPA product with paying users: SaaS, a CRM, an ERP, a marketplace. Sessions and rate counters in the cache, model calls and mail and exports on the queue, so a slow answer never holds a page open.At the shared runtime, and at the size of a single application. The capacity is real, but it is spent on a node shared with other Teams, and the biggest shape one application may take here is half the pot - the size above it is the whole of it, which is why that one is Business.
Business$299/mocompany-wide, fully isolatedA company running its own portfolio - dozens of internal tools, several products, a team per project - on a runtime cluster nobody else is scheduled onto.At the project count, and that one is not a wall: an additional project is bought as an add-on, one at a time, and the cluster's own limits are set for the customer rather than for a pool.

Before any of them there are seven days of the whole thing - one application and one database - which exists so the loop can be tried before a tier is chosen. What it is not is a plan: nothing stays running on the free tier a trial lands on.

Two boundaries above are worth stating on their own, because both are usually discovered late. An application never has a disk, on any plan - so on a tier without a service there is genuinely nowhere to keep anything. And a cache and a queue arrive together, at the tier where a Team is running enough for either to be the thing that was missing.

Which leaves the last question - what happens between a commit and something you can open.

Connecting

Connecting a database: ours, or one you already have

The runtime is ours. Your data does not have to be. A project hosted here can keep its records in a database aidrop runs beside it, or in one you already pay for somewhere else, and the choice is not made once for the account - it is made per project, and it can change.

Three ways to give a project a database

RouteReach for it whenWhat it costs you here
One aidrop runsYou are starting from nothing, or you want one less account and one less bill. It is provisioned, connected and backed by a volume without you configuring anything.Memory and CPU from the plan's pot. Available from the tier that includes a database.
One you already have, over its HTTP interfaceYou already run a database elsewhere and your provider puts a REST layer or a client library in front of it. Your data stays where it is, under your account and your backup policy.Nothing. It needs no plan feature and works on every tier that hosts anything.
Something that is not a database at allA payment provider, a mail sender, a search index, a model API - the same mechanism, and most of what a project talks to is this.Nothing.

Attaching one you already have

There is no integration to install and no adapter to write. Store the address as a value on the project, deploy, and your code reads it out of its environment under the name you gave it - the same line of code it would use anywhere else. If your project already runs somewhere and already reads a connection string from its environment, there is nothing to change: give the value the name the code already expects.

One thing to know about how a value gets in. Your agent writes it - there is a tool that takes a name and a value, and the dashboard deliberately has no form for it, because the page could only ever show you that a name exists: no surface here answers a stored value back to anybody, including us. What follows from that is worth saying plainly: a value you hand an agent has passed through a model on the way, so a credential you are unwilling to put in a conversation should be rotated into one you are - and a value is never returned once stored, so the only way to change one is to write it again.

What a project can reach, and what it cannot

This is the one constraint to design around, and it is about the port rather than the provider. Outbound traffic leaves a project through an HTTP proxy: only HTTP on 80 and HTTPS on 443 leave it.

Reaching outwardWorksWhy
A provider's HTTPS API - REST, a client library built on it, auth, object storageYesPort 443 is what the proxy carries. Use a client that honours HTTP_PROXY and HTTPS_PROXY; most standard libraries do, and any client that opens its own socket is worth checking.
A database over its own wire protocol - a `postgresql://…:5432` string, or a pooler portNoA raw socket to any port other than 80 or 443 does not leave the project. It is refused rather than slow, so you find out at once.
A database aidrop runs beside the applicationYesThat traffic stays inside the project and never touches the proxy, so no port rule applies.

Read as a rule for building: if the service you want has an HTTPS API, connect to it and keep your data where it already is. If you need the database protocol itself - an ORM speaking to Postgres directly, a migration tool, a psql session from your application - that database has to be one running beside your application, which is what the managed one is for.

The restriction is not incidental. An application that can open an arbitrary socket to an arbitrary port is the shape abuse takes, and the same rule is what stops mail being sent and ports being scanned from an address we issued to somebody else.

More than one, and moving between them

A project can read several databases at once, each under its own name, which is what makes a move survivable: attach the new one beside the old, run both while you copy, then drop the name you no longer read. What a project cannot do is read two things under one name - asking for that is refused when you ask, rather than at the deploy that would have quietly picked one.

Nothing here locks a project in either direction. A project that started on a database aidrop runs can move to your own account, and one that arrived pointing at your own can be handed a managed database later without touching its code - both are a value under a name.

What all of it is for: getting a commit to an address somebody can open.

Delivery

From a commit to an address

Five steps, each of which leaves a record. If it stops, the record says at which stage and why, rather than leaving you to infer it from a log.

  1. Connect

    A GitHub repository, or one in your Team's own Git. The code stays where it is; aidrop indexes the current revision.

  2. Settle

    Assign an owner and name the runtime contract the code needs: the port it listens on, its health endpoint, the values it reads.

  3. Authorise

    Connect the agent you use over MCP. It reaches your Team's Services and nothing outside them, and you can revoke it in the dashboard.

  4. Build

    One pipeline record with explicit stages and, if it stops, a stop reason. The step that runs your code holds no credential.

  5. Serve

    The address answers from that first deploy, and it is open to the internet. Put a name you own in front of it whenever you like.

That address is one we issue. The last page is what it is made of, and how a name you own takes its place in front of it.

Domains

Addresses: the one you get, and the one you own

A project answers on an address from the moment it first deploys. You do not ask for one and you do not choose it - asking would put a decision you have no basis to make between you and a running application. Putting a name you own in front of it is a separate, deliberate step, and it is the whole of this page.

The address you are given

It is derived from the Service's identifier: app- and eight characters, under the zone of the cluster serving it. Derived from the identifier rather than the name, because a name gets edited, and an address that moves when somebody fixes a typo is worse than an opaque one.

One property of it is worth knowing before you plan around it: the zone belongs to the cluster, not to the platform. There is no single suffix every address on aidrop shares - a second cluster serves its own names, and a project that moves to one gets names from there. So the target you eventually point your own DNS at is the one your project's page shows you, and it is not the one somebody else was given.

That address is open. It answers to anyone who has it from the moment the first deploy finishes, which is the one thing on this page worth knowing before you push.

Pointing a name you own at it

Included from Pro. Three steps, none of which is a screen or a support ticket: your agent claims the hostname and is handed the one record to create, you create it at your DNS provider, your agent verifies it. The claim holds the name against every other Service from that moment and publishes nothing - the record you are shown is the record to create, with the type and the target already decided for you. If your provider does not add the trailing dot to a CNAME value for you, type it: a zone that reads the value as relative will quietly append your own domain to ours.

What you are pointingThe recordNotes
app.example.comCNAME → the target your project showsA name with a subdomain in front of it. The ordinary case, and the one nothing complicates.
example.comSee belowThe domain itself cannot hold a CNAME. It is the one case that needs a paragraph, and it has one.

Verification is a request, not a lookup, and everything else here follows from that. We do not resolve your record and look for ourselves in the answer; we ask the hostname for a token and count it only if the answer comes back. So nothing is checked against what your record says - only against whether traffic for that name arrives here, which is the fact worth proving anyway.

Two consequences you get for free. A proxy in front of your DNS changes nothing, because a proxy cannot hide a request the way it hides a record. And the hostname exposes nothing while it is being proved: the route holds the token and has no application behind it, so there is no window in which a half-configured name serves your project to the world.

A certificate is issued once requests for the name reach us, so a hostname pointed a minute ago can take a few more before it answers over HTTPS. Verify is safe to press again. And one hostname belongs to one project: the first claim holds it.

The domain itself, and what a flat CNAME is

example.com - the second-level domain, the apex of your zone - is the one place where “just add a CNAME” does not work, and the reason is not a policy of ours. A CNAME means this name is an alias for that one and has no records of its own. The apex is obliged to carry the records that make the zone exist at all. Both cannot be true of the same name, so the apex cannot be a CNAME, and a DNS provider that lets you save one is doing something else underneath.

That something else is what “flat CNAME” names. Your DNS provider accepts a CNAME on the apex, resolves it itself, and answers the world with the addresses it got back - a CNAME to you, plain address records to everyone asking. Cloudflare calls it CNAME flattening; elsewhere the same idea is sold as ALIAS or ANAME. It is the right answer wherever it is offered, because the alias is re-resolved rather than frozen: if the project later moves to another cluster, the name follows without you editing anything.

OptionWhat you doWhat it costs you
Flattened CNAME, ALIAS or ANAMEEnter the target as a name on the apex and let the provider resolve it.Nothing. Prefer this wherever your provider has it.
A recordResolve the target yourself and enter the addresses it gives.It works with every provider, and it is fixed: an address does not follow the project if it moves. You would have to edit it.
A subdomain plus a redirectRun the project on www., where an ordinary CNAME works, and redirect the bare domain to it.One extra hop for a visitor who types the bare name. The fallback when a provider offers neither of the above.

If your domain is on Cloudflare

It is supported and it needs nothing special from us. Three of its settings decide how smooth it is, and only the last one is a trap.

SettingWhat to doWhy
The proxy - the orange cloudOn or off. Both verify.This is the payoff of proving by request. Proxied, your record answers with Cloudflare's own addresses and what is underneath is invisible to everyone - so any check that read DNS would fail a domain that is configured correctly. We do not read DNS.
CNAME flatteningLeave it on for the root record, which is where Cloudflare applies it by default.It is what lets the apex hold what looks like a CNAME at all. If you are pointing example.com rather than a subdomain, this is the setting doing the work.
SSL/TLS - the origin connectionFull, or Full (strict). Not Flexible.With the proxy on, Cloudflare decides for itself how it reaches us. Flexible fetches your application over plain HTTP: the padlock your visitor sees is Cloudflare's alone, and the leg from Cloudflare to your project is not encrypted. Full keeps it end to end.

Nothing else needs changing. Our edge answers on both HTTP and HTTPS rather than bouncing one to the other, so no proxy mode here produces the redirect loop this arrangement is famous for.

When a plan lapses the application stops, and none of this stops being useful: the repository, the record of every build and the access are the part that never depended on the application running.

Next

Try it against a codebase you already have

Seven days, no card. Connect a repository, point your agent at it, and read the record it produces before you decide anything.

Start 7-day Project trial