Overview
The project transfer functionality enables you to provision fully-configured Postgres databases on behalf of your users and seamlessly transition ownership. This capability eliminates the technical overhead of database setup while ensuring your users maintain complete control of their database resources.
Availability Status
This feature is available in private preview only. To enable this functionality for your account, contact our partnership team.
Simplified workflow
-
Create a Neon project on behalf of your user in your account or organization
- This provides them with a Postgres connection string for their application immediately
-
Create a transfer request for the project
- This generates a unique, time-limited transfer request ID
-
Share a claim URL with your user
- This URL contains the project ID and transfer request ID
-
User claims the project
- When they click the URL, Neon transfers the project to their account
Step-by-step guide
Create a Neon project
Use the Neon create project API to create a new project that you intend to transfer to your user.
The minimum request body is
project: {}
as all settings are optional.API endpoint
POST https://console.neon.tech/api/v2/projects
Example request
curl -X POST 'https://console.neon.tech/api/v2/projects' \ --header 'Accept: application/json' \ --header 'Authorization: Bearer {your_api_key_here}' \ --header 'Content-Type: application/json' \ --data '{ "project": { "name": "new-project-name", "region_id": "aws-us-east-1", "pg_version": 17, "org_id": "org-cool-breeze-12345678" } }'
This creates a new project with:
- A default branch named
main
- A default database named
neondb
- A default database role named
neondb_owner
- A project named
new-project-name
(defaults to the project ID if not specified) - The project in the
org-cool-breeze-12345678
organization - PostgreSQL version 17 in the
aws-us-east-1
region (these settings are permanent)
Example response
Below is an abbreviated example of the response. For brevity, this documentation shows only key fields. For the complete response structure and all possible fields, see the API documentation.
{ "project": { "id": "your-project-id", "name": "new-project-name", "owner_id": "org-the-owner-id", "org_id": "org-the-owner-id" }, "connection_uris": [ { "connection_uri": "postgresql://neondb_owner:{password}@ep-cool-shape-123456.us-east-1.aws.neon.tech/neondb?sslmode=require" } ], "branch": {}, "databases": [{}], "endpoints": [{}], "operations": [{}], "roles": [{}] }
Your user will need the connection string from the response (
connection_uri
) to connect to the Neon database. The{password}
placeholder represents the actual password generated for the database. You'll also use the projectid
to create a transfer request.- A default branch named
Create a transfer request
With your project created, use the Neon project transfer request API to generate a transfer request. You can create this request immediately or at a later time when you're ready to transfer the project. Each transfer request has a configurable expiration period, specified by the
ttl_seconds
parameter.API endpoint
POST https://console.neon.tech/api/v2/projects/{project_id}/transfer_requests
Example request
curl -X POST 'https://console.neon.tech/api/v2/projects/{project_id}/transfer_requests' \ --header 'Accept: application/json' \ --header 'Authorization: Bearer {your_api_key_here}' \ --header 'Content-Type: application/json' \ --data '{ "ttl_seconds": 604800 }'
This example sets a one-week expiration (604,800 seconds). The default is 86,400 seconds (24 hours).
Example response
{ "id": "389ad814-9514-1cac-bc04-2f194815db76", "project_id": "your-project-id", "created_at": "2025-05-18T19:35:23Z", "expires_at": "2025-05-25T19:35:23Z" }
If transfer requests are not enabled for your account, you'll receive:
{ "request_id": "cb1e1228-19f9-4904-8bd5-2dbf17d911a2", "code": "", "message": "project transfer requests are not enabled for this account" }
Share the claim URL
Construct a claim URL to share with your user using the following format:
https://console.neon.tech/app/claim?p={project_id}&tr={transfer_request_id}&ru={redirect_url}
Where:
p={project_id}
- The project ID being transferredtr={transfer_request_id}
- The transfer requestid
from the previous stepru={redirect_url}
(optional) - A URL-encoded destination where the user is redirected after successfully claiming the project- Without this parameter, users remain on the Neon project page after claiming
- This allows your application to detect successful claims when users return to your site, enabling you to trigger next steps in your onboarding flow
User communication
When sharing the claim URL, inform your user that:
- They'll need a Neon account to claim the project (they can create one during the claim process)
- The link will expire at the time shown in the
expires_at
field - After claiming, they'll have full ownership of the project
- The database connection string remains unchanged (though they should update the password for security)
User claims the project
Via browser (recommended)
When your user clicks the claim URL:
- Neon prompts them to log in or create an account
- After authentication, Neon displays a confirmation screen
- If they belong to organizations, they can select the destination:
- Their personal account
- Any organization where they have membership
- Upon confirmation, Neon transfers the project
- The user is then:
- Redirected to your application if
ru
parameter was provided, allowing you to detect the successful claim and continue your onboarding flow - Kept on the Neon project page if no redirect URL was specified
- Redirected to your application if
Via API
Alternatively, users can accept the transfer request programmatically using the accept project transfer request API.
API endpoint
PUT https://console.neon.tech/api/v2/projects/{project_id}/transfer_requests/{request_id}
Example request (transfer to organization)
curl -X PUT 'https://console.neon.tech/api/v2/projects/{project_id}/transfer_requests/{request_id}' \ --header 'Accept: application/json' \ --header 'Authorization: Bearer {users_api_key_here}' \ --header 'Content-Type: application/json' \ --data '{ "org_id": "org-cool-breeze-12345678" }'
Without the
org_id
parameter, the project transfers to the user's personal account. With it, the project transfers to the specified organization where the user has membership.
Important notes
Transfer request behavior
- Expiration: Requests expire after the specified
ttl_seconds
(default: 24 hours). Once expired, you must create a new transfer request - One-time use: Each transfer request can only be used once
- Already claimed: If a project has already been claimed, subsequent attempts will fail with an error
Security considerations
- URL security: Share claim URLs through secure channels as anyone with the URL can claim the project
- Password rotation: Instruct users to change their database password immediately after claiming
- Access revocation: Once transferred, you lose all access to the project unless the new owner grants permissions
Technical details
- Connection persistence: Database connection strings remain valid after transfer
- Organization transfers: Users must be members of the target organization
- Organization ID format:
org-[descriptive-term]-[numeric-id]
(e.g.,org-cool-breeze-12345678
)
Example use cases
- SaaS applications - Provision databases for your SaaS users that they can later claim and manage
- Development agencies - Create database projects for clients and transfer ownership upon project completion
- Educational platforms - Set up pre-configured database environments for students
- Demo environments - Create ready-to-use demo databases that prospects can claim
- Team environments - Provision project databases for team members to claim into their organization
For a working implementation of claimable databases, try Neon Launchpad. This service demonstrates the complete flow: users receive a Postgres connection string immediately without creating an account, and databases remain active for 72 hours. To retain the database beyond this period, users claim it by creating a Neon account using the provided transfer URL. See the Neon Launchpad documentation for implementation details. This same pattern enables SaaS providers to offer instant database provisioning while allowing users to take ownership when ready.
Troubleshooting
Issue | Solution |
---|---|
Claim URL expired | Create a new transfer request and generate a new claim URL |
User receives error when claiming | Verify the project exists and the transfer request hasn't been used |
Project doesn't appear after claiming | Refresh the Neon Console or log out and back in |
"Transfer requests not enabled" error | Contact our partnership team to enable this private preview feature |
Organization transfer fails | Verify user membership in the target organization and correct org_id format |
Already claimed error | The transfer request has been used; create a new one if needed |