# Moving your app off Somewhere Keep your source, export your data and files, and replace the platform services one at a time. This guide maps those services to what you need on another host. ## Collect the parts of your app | What you need | How to get it | |---|---| | Live source | `somewhere pull --out my-app`, using a new folder, or `project_export({ project_id })` over MCP | | Database schema and rows | `somewhere db dump --output backup.sql` or `db_dump({ project_id })` | | One table as CSV | `db_export({ project_id, table, filters })` in the full MCP tool set, or `POST /v1/db/export` | | Uploaded files | List directories and read each path with `fs_read`, or `GET /v1/fs//` | | Complete user IDs and emails | Page through `GET /v1/auth/users/inventory?project_id=` with a developer key | | User profiles | `GET /v1/auth/users?project_id=`; batch inventory IDs through its `ids` lookup; see `portability` for the batch limit | | Environment variables | List names with `GET /v1/env`; retrieve secret values from your own records or their providers | | Password credentials | Exporting password credentials is not available; users set a password at the destination | Run exports from your own server or terminal. Keep the developer key out of browser code. The API host is `https://api.somewhere.cloud`. The database dump captures schema, rows and sequence state together. If any table or the capture exceeds its supported limits, the request returns an error instead of SQL for the whole database. Export every table as CSV — large tables in disjoint filtered ranges — and recreate the schema from `db/schema.ts` or `db_describe`. See `docs({ topic: 'portability' })` for the limits, commands, capture receipt and restore steps. App accounts are stored separately from your project database. A database may contain an `auth_users` copy for joins; it can be incomplete. Use the user inventory for the export, follow `next_cursor` until it is empty, and compare your collected IDs with `total`. Each page includes its own checksum. Passwords are stored as bcrypt hashes. Exporting password credentials is not available, so users set a password at the destination and sign in again after the move. ## Restore the database and its access rules The SQL dump uses the source database's dialect. Restore it into that engine, or convert the schema and data for your destination. Function code and the developer SQL tools translate different sets of Postgres forms; `docs({ topic: 'sql-compatibility' })` lists both, including differences in query results. Review queries as well as schema during a move to another engine. Access rules need their own transfer. Table-access labels travel as comments in the dump; importing SQL does not enforce those rules. Translate your `db/schema.ts` owner, member and visitor rules into the destination's authorization checks. Also transfer sensitive-column restrictions, membership relationships and any checks in your handlers. Before switching traffic, check row counts, relationships and full-text search, then sign in as two test users and check what each can read and change. Also inventory the other services your app uses, such as inbox, jobs, video, analytics and logs. Read their export and retention controls in the relevant topic; a database dump covers the tables in your project database. ## Replace the services your code uses Your source is React and TypeScript, and function requests use the Web `Request` API. On the new host, provide a build and routing setup, replace `sw.*` calls and generated `somewhere:data`, `somewhere:files` and `somewhere:api` clients, and implement the access rules your app relies on. | Somewhere service | What to provide on the destination | |---|---| | `sw.db`, declared data and `db/schema.ts` | A SQL database, migrations, query client and row authorization | | `sw.auth` | Accounts, cookie sessions, sign-in protection and any magic-link or OAuth flows your app uses | | `sw.fs` and declared files | File storage plus upload, download and ownership checks | | `sw.email`, `sw.inbox`, `sw.contacts` | Sending, inbound delivery, contacts and delivery-status handling | | `sw.ai` | Model-provider clients and your app's spend limits | | `sw.image` | Image transformations and delivery | | `sw.payments` and `sw.billing` | Checkout, verified webhooks, fulfillment and subscriptions | | `sw.jobs`, `sw.cron` | Workers, durable queues, delayed starts, schedules and progress tracking | | `sw.db.live` and `watchLive` | Authorized live subscriptions and reconnect handling | | `sw.search` | Indexing, retrieval and permissions on search results | | `sw.render` | Browser-based PDF and screenshot generation | | `sw.rateLimit` | Counters and rate-limit enforcement | | `sw.analytics` | Event ingestion, queries and consent handling | | `sw.push`, `sw.notifications` | Device subscriptions and notification delivery | | `sw.logs` | Log collection, access controls and retention | | `sw.web` | Fetching, scraping and web search | | `sw.crypto` | Cryptographic functions in your server runtime | | `sw.tasks`, `sw.calendar` | Their data, API behavior and permissions | | `sw.env` | Your host's environment variables and secrets | The platform does not rewrite these calls for you. Work through the services actually used by your app and verify each flow as you replace it. ## Move one service at a time You can keep using Somewhere from your own backend while moving other parts. Most services have REST endpoints on `https://api.somewhere.cloud/v1/*`; `docs({ topic: 'api-surface' })` lists their methods and authentication. Local helpers such as `sw.crypto` and URL builders such as `sw.image` have no equivalent platform request. A management endpoint can also differ from a runtime helper: `GET /v1/env` lists variable names, not secret values. Use developer credentials only on your server. Keep the current cookie-based browser flows until you have replaced their server-side authentication and authorization. Plan limits still apply to the services you retain; read `GET /v1/pricing` for the current allowances. To attach an external PostgreSQL database while keeping the app on Somewhere, see `docs({ topic: 'postgres' })`. Attaching it does not move existing data. ## Switch traffic Use a custom domain you control, move its DNS when the destination is ready, and keep the old app available for the rollback window you choose. The `somewhere.site` subdomain stays with Somewhere. The dashboard and platform review tools stay here too; your source, data and files are yours to move. Related: , `docs({ topic: 'portability' })`, `docs({ topic: 'sql-compatibility' })`, `docs({ topic: 'security-model' })`, `docs({ topic: 'sw.env' })`.