---
title: "Name the principal that receives a transferred project's source"
method: POST
path: "/agent/v1/transfers/{transfer_id}/vault-handover"
tags: ["Project Transfers"]
---

# Name the principal that receives a transferred project's source

`POST /agent/v1/transfers/{transfer_id}/vault-handover`

## Request

- Base URL: `https://api.run402.com`
- URL: `https://api.run402.com/agent/v1/transfers/{transfer_id}/vault-handover`
- Auth: one of:
  - API key in header `SIGN-IN-WITH-X`
  - HTTP bearer

The recipient of a pending transfer names itself as the principal that receives the project's vault. Authorized like accept for the row's kind: the recipient wallet's SIWX for a wallet-addressed transfer, a principal whose verified email matches for an email-addressed one. The caller must have a published keystore identity (both halves, possession-verified). Idempotent for the same principal; a different principal replaces the nomination only while the handover is incomplete. Emits `transfer_vault_handover_requested` to the project's feed. `run402 transfer accept` calls this automatically.

## Path parameters

- `transfer_id` string, uuid, required

## Response `200`

The nomination and the handover's current state, with one next action: `complete_vault_handover` (the sender's `run402 transfer handover`) or, once complete, accept.

- object
  - `transfer_id` string, uuid
  - `vault_handover` object, nullable: The vault handover this transfer requires; null when the project has no admitted vault. A transfer moves the project's KyGit vault, and the gateway never holds its key, so the recipient names the principal that receives the source (POST /agent/v1/transfers/{transfer_id}/vault-handover), the sender's writer admits that principal's key and wraps the source key for it (`run402 transfer handover <transfer_id>`), and only then can accept succeed. `state` is derived from the vault's writer set and envelopes at read time.
    - `repo_id` string
    - `state` 'awaiting_recipient' | 'awaiting_sender' | 'complete'
    - `recipient_principal_id` string, uuid, nullable
    - `recipient` object, nullable: The nominee's published keystore identity (public keys only) the sender's writer admits and wraps to.
      - `principal_id` string, uuid
      - `writer_key_id` string
      - `signing_pubkey` string
      - `ek_fingerprint` string
      - `public_key` string
    - `current_epoch` string: 16 lowercase hex: the vault's current epoch.
    - `writer_admitted` boolean
    - `envelope_current_epoch` boolean
  - `next_actions` object[]

## Other responses

- `401`: INVALID_AUTH
- `403`: FORBIDDEN — the caller is not this transfer's recipient
- `404`: TRANSFER_NOT_FOUND
- `409`: VAULT_WRITER_KEY_UNPUBLISHED (publish a keystore identity first) / TRANSFER_VAULT_HANDOVER_PRINCIPAL_MISMATCH (the source was already handed to a different principal) / TRANSFER_ALREADY_PROCESSED / VALIDATION_FAILED (an org-addressed transfer, or a project with no vault)
- `410`: TRANSFER_EXPIRED
- `412`: CONTACT_EMAIL_NOT_VERIFIED

---

[API](https://skmtc.dev/run402/apis/run402-api.md) · [All operations](https://skmtc.dev/run402/apis/run402-api/llms.txt) · [OpenAPI document](https://skmtc.dev/run402/apis/run402-api/revisions/893607557f50?raw)
