Project Transfers

Initiate a project transfer (to a wallet, email, or owned org)

Transfer a project to another owner. Address the recipient by EXACTLY ONE of to_wallet (a two-party SIWX transfer completed via /accept), to_email (an email-addressed transfer, also accepted via /accept), or to_org_id (same-actor move into another org the caller already owns, completed synchronously). Supplying multiple recipient fields, or none, returns 400 VALIDATION_FAILED. Email-addressed transfers may include retain_member: { role: "developer" }; wallet/org-addressed transfers reject it. kysigned_record_id is wallet-only. Either pending party can cancel wallet/email transfers; otherwise they auto-expire at 72h. Single-pending-per-project (partial UNIQUE index) → 409 PENDING_TRANSFER_EXISTS. Auth: SIWX wallet, or a control-plane session (step-up gated). Org-addressed same-actor moves require active owner membership on both source and destination orgs; non-same-actor org transfers are reserved for a future interactive flow and currently return 403 FORBIDDEN.

post/projects/v1/{project_id}/transfers

Request

  • Base URL: https://api.run402.com
  • URL: https://api.run402.com/projects/v1/{project_id}/transfers
  • Auth: one of:
    • API key in header SIGN-IN-WITH-X
    • HTTP bearer

Path parameters

project_idstring required

Run402 project ID. Public IDs are not UUIDs.

Example:prj_1741340000_0042

Request body

to_walletstring

Recipient wallet address (canonical-lowercase). Mutually exclusive with to_email and to_org_id; must differ from the initiator. Completed via POST /agent/v1/transfers/{transfer_id}/accept.

to_emailstring email

Recipient email address. Mutually exclusive with to_wallet and to_org_id. The recipient accepts via POST /agent/v1/transfers/{transfer_id}/accept with a sign-in session whose verified email matches, choosing an org they own or creating a new one.

to_org_idstring uuid

Destination org id for a same-actor move. Mutually exclusive with to_wallet and to_email. In this version, the caller must be an active owner of both the source org and destination org; the move completes synchronously with a 200 response.

billing_policy'migrate'

Phase 1A only supports 'migrate' (single billing-migration mutation). 'inherit' returns 400 INVALID_BILLING_POLICY.

messagestring

Optional human-readable note carried in notification emails to both parties.

kysigned_record_idstring

Wallet-addressed transfers only. Optional KySigned attestation record id. Recorded as-is in Phase 1A; verification ships in Phase 1B.

Response

Same-actor org transfer completed synchronously. Returned only for to_org_id when the caller owns both orgs.

transfer_idstring uuid
project_idstring
from_org_idstring uuid
to_org_idstring uuid
completed_atstring date-time
secrets_rotation_advisedtrue
secret_names_inheritedstring[]

Names of every secret currently on the project. Values transfer with the project but are never returned.

secrets_count_inheritedinteger
github_repo_notestring
ci_bindings_suspendedinteger

Count of CI/OIDC (ci_oidc) bindings revoked by this move. When > 0, push-to-deploy is suspended until re-linked (run402 ci link github).

ci_bindings_notestring

Present only when ci_bindings_suspended > 0: explains the CI/OIDC revocation and how to re-link.

anon_keystring

JWT for client-side access to the moved project (apikey header).

service_keystring

JWT for admin access to the moved project (Authorization: Bearer).

Changes

No recorded changes to this operation across all 1 revision of this API.