---
title: "Hand over a client project"
method: POST
path: "/clients/{id}/transfer"
tags: ["Agencies"]
---

# Hand over a client project

`POST /clients/{id}/transfer`

## Request

- Base URL: `https://api.hypamoon.com/api/v1`
- URL: `https://api.hypamoon.com/api/v1/clients/{id}/transfer`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://app.hypamoon.com/oauth/authorize`, token URL `https://api.hypamoon.com/oauth/token`, scopes: `clients:write`)

Hands over a project in the building stage. With to_email the client becomes the owner after accepting on their own confirmation page; agency_keeps_access says whether your agency keeps working on it (true) or stops (false, then the client pays from then on). With to_agency_project_id another agency takes it over after an owner or builder there accepts in their portal (Clients); your access ends at that moment. A project the client already owns cannot be handed over: the client chooses its agencies. The answer lists open_payments: your payment links and subscriptions for this client, to cancel what should stop.

## Path parameters

- `id` string, uuid, required

## Request body

- object
  - `to_email` string, email
  - `agency_keeps_access` boolean
  - `to_agency_project_id` string, uuid
  - `message` string

## Response `202`

The handover waits for the receiving side.

- object
  - `object` 'client_relation', required
  - `id` string, uuid, required
  - `agency` object, required
    - `project_id` string, uuid, required
    - `name` string, required
  - `client` object, required
    - `project_id` string, uuid, required
    - `name` string, required
  - `status` 'pending' | 'active' | 'declined' | 'ended', required
  - `stage` 'building' | 'client_owned', required
  - `role` 'viewer' | 'builder' | 'admin', required
  - `max_mode` 'test' | 'live', required
  - `four_eyes` boolean, required
  - `payer` 'client' | 'agency', required
  - `budget_eur` number, nullable, required
  - `payer_change` object, nullable, required
    - `to` 'client' | 'agency', required
    - `proposed_by` 'client' | 'agency', required
    - `proposed_at` string, nullable, required
  - `owner_invite` object, nullable, required
    - `email` string, required
    - `expires_at` string, nullable, required
    - `agency_keeps_access` boolean, required
  - `confirmed_at` string, nullable, required
  - `ended_at` string, nullable, required
  - `created_at` string, required
  - `transfer` object
    - `direction` 'incoming' | 'outgoing', required
    - `agency` object, required
      - `project_id` string, uuid, required
      - `name` string, required
    - `relation_id` string, uuid, required
    - `expires_at` string, nullable, required
  - `ended_via` 'client' | 'agency' | 'admin' | 'handover' | 'expired' | 'cleanup'
  - `cleanup` object
    - `phase` 'notified' | 'trash' | 'deleted', required
    - `trash_on` string, required
    - `delete_on` string, required
  - `transfer_relation` object
    - `object` 'client_relation', required
    - `id` string, uuid, required
    - `agency` object, required
      - `project_id` string, uuid, required
      - `name` string, required
    - `client` object, required
      - `project_id` string, uuid, required
      - `name` string, required
    - `status` 'pending' | 'active' | 'declined' | 'ended', required
    - `stage` 'building' | 'client_owned', required
    - `role` 'viewer' | 'builder' | 'admin', required
    - `max_mode` 'test' | 'live', required
    - `four_eyes` boolean, required
    - `payer` 'client' | 'agency', required
    - `budget_eur` number, nullable, required
    - `payer_change` object, nullable, required
      - `to` 'client' | 'agency', required
      - `proposed_by` 'client' | 'agency', required
      - `proposed_at` string, nullable, required
    - `owner_invite` object, nullable, required
      - `email` string, required
      - `expires_at` string, nullable, required
      - `agency_keeps_access` boolean, required
    - `confirmed_at` string, nullable, required
    - `ended_at` string, nullable, required
    - `created_at` string, required
    - `transfer` object
      - `direction` 'incoming' | 'outgoing', required
      - `agency` object, required
        - `project_id` string, uuid, required
        - `name` string, required
      - `relation_id` string, uuid, required
      - `expires_at` string, nullable, required
    - `ended_via` 'client' | 'agency' | 'admin' | 'handover' | 'expired' | 'cleanup'
    - `cleanup` object
      - `phase` 'notified' | 'trash' | 'deleted', required
      - `trash_on` string, required
      - `delete_on` string, required
  - `open_payments` object[], required
    - `object` 'client_payment_link' | 'client_subscription', required
    - `id` string, uuid, required
    - `client_project_id` string, uuid, required
    - `status` 'open' | 'paid' | 'failed' | 'expired' | 'active' | 'canceled', required
    - `amount_cents` integer, required
    - `fee_cents` integer, required
    - `currency` string, required
    - `description` string, required
    - `interval` 'month' | 'year' | 'null', nullable
    - `paid_until` string, nullable
    - `canceled_at` string, nullable
    - `test` boolean, required
    - `checkout_url` string, nullable, required
    - `paid_at` string, nullable, required
    - `created_at` string, required

## Other responses

- `400`: Bad Request: invalid_json.
- `401`: Unauthorized: unauthorized, missing_api_key, invalid_api_key, api_key_revoked, project_deleted.
- `403`: Forbidden: project_not_enabled, key_mode_mismatch, missing_scope, verification_required, forbidden.
- `404`: Not Found: not_found.
- `409`: Conflict: conflict.
- `422`: Unprocessable Content: validation_failed.
- `429`: Too Many Requests: rate_limited.
- `500`: Internal Server Error: internal_error.
- `503`: Service Unavailable: service_unavailable.

---

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