---
title: "join_product"
description: "Generated reference for the management action join_product: its description, access metadata, payload contract, and registration status."
slug: /reference/actions/join-product
order: 6
visibility: public
redirects_from: []
---

# join\_product

Generated automatically from the [published contract sources](/reference/about#contract-sources).

**Build metadata:** Registered in this build. Registration describes the default dispatcher in this build. It does not guarantee that a caller has the required credential or grant, that a tool is listed for that connection, or that the required service is configured.

A script calls this action over HTTPS at `POST https://turnzero.ai/api/v1/actions/join_product`, with a bearer credential and the action's payload as the JSON body.

## Contract description

Add tzCloud to this account, the act the account page's Enable control makes\. Name \`product\` as \`cloud\`\. The join takes one of Cloud's open places and is refused \`realm\_creation\_ceiling\` while none is open; an invitation that names Cloud adds it whatever the count\. An account that already holds Cloud answers \`joined: false\` with nothing changed\. Refused \`account\_door\_not\_yet\_served\` on an estate whose operator has not lifted the account door\. tzTeam comes by invitation; no other product is joined here\.

## Access and action metadata

```json
{
  "name": "join_product",
  "resource": "account",
  "tier": "reversible",
  "clients": [
    "bearer",
    "browser_session"
  ],
  "summary": "Add tzCloud to the acting account, the account page's join: `product` names `cloud`, the one product a join adds at this revision; the grant counts against the operator's ceiling on open sign-ups and is refused `realm_creation_ceiling` where the open sign-ups stand at it, recorded on the operator's side; an account already holding the product answers `joined: false` with nothing changed. Refused `account_door_not_yet_served` while the estate's ACCOUNT_DOOR_PRODUCTS setting reads off. tzTeam comes by invitation; no other product is joined here, each refused `invalid_request`.",
  "annotations": {
    "readOnlyHint": false,
    "destructiveHint": false,
    "openWorldHint": false,
    "idempotentHint": true
  }
}
```

## MCP catalog entry

```json
{
  "name": "join_product",
  "title": "Enable tzCloud",
  "tier": "reversible",
  "scenario": "CHI-L0-04",
  "summary": "Add tzCloud to this account, the act the account page's Enable control makes. Name `product` as `cloud`. The join takes one of Cloud's open places and is refused `realm_creation_ceiling` while none is open; an invitation that names Cloud adds it whatever the count. An account that already holds Cloud answers `joined: false` with nothing changed. Refused `account_door_not_yet_served` on an estate whose operator has not lifted the account door. tzTeam comes by invitation; no other product is joined here.",
  "owners": [
    "ACB-L0-76",
    "ACB-L0-77",
    "WEB-L0-21"
  ]
}
```

## request

| JSON pointer | Description and constraints |
|---|---|
| "" \(root\) | Type: object<br>Required fields: \["product"\]<br>Additional properties: false |
| /<wbr>properties/<wbr>product | The product to join, \`cloud\` at this revision: tzTeam comes by invitation; no other product is joined here, each refused \`invalid\_request\`\.<br><br>Allowed values: \["cloud"\] |

## response

| JSON pointer | Description and constraints |
|---|---|
| "" \(root\) | Type: object<br>Required fields: \["contract\_version","account","product","joined"\]<br>Additional properties: false |
| /<wbr>properties/<wbr>contract\_version | Required value: 1 |
| /<wbr>properties/<wbr>account | Type: object<br>Required fields: \["id","created\_at","standing","synthetic"\]<br>Additional properties: false |
| /<wbr>properties/<wbr>account/<wbr>properties/<wbr>id | Type: string |
| /<wbr>properties/<wbr>account/<wbr>properties/<wbr>created\_at | Type: string |
| /<wbr>properties/<wbr>account/<wbr>properties/<wbr>standing | Allowed values: \["active","suspended"\] |
| /<wbr>properties/<wbr>account/<wbr>properties/<wbr>synthetic | Type: boolean |
| /<wbr>properties/<wbr>product | The profile name the call named\.<br><br>Type: string |
| /<wbr>properties/<wbr>joined | true where the account lacked the product and now holds it; false where it already held it, nothing changed, and a repeat answers the same\.<br><br>Type: boolean |
| /<wbr>properties/<wbr>detail | Type: string |

## Complete payload contract

```json
{
  "request": {
    "type": "object",
    "required": [
      "product"
    ],
    "properties": {
      "product": {
        "enum": [
          "cloud"
        ],
        "description": "The product to join, `cloud` at this revision: tzTeam comes by invitation; no other product is joined here, each refused `invalid_request`."
      }
    },
    "additionalProperties": false
  },
  "response": {
    "type": "object",
    "required": [
      "contract_version",
      "account",
      "product",
      "joined"
    ],
    "properties": {
      "contract_version": {
        "const": 1
      },
      "account": {
        "type": "object",
        "required": [
          "id",
          "created_at",
          "standing",
          "synthetic"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "standing": {
            "enum": [
              "active",
              "suspended"
            ]
          },
          "synthetic": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "product": {
        "type": "string",
        "description": "The profile name the call named."
      },
      "joined": {
        "type": "boolean",
        "description": "true where the account lacked the product and now holds it; false where it already held it, nothing changed, and a repeat answers the same."
      },
      "detail": {
        "type": "string"
      }
    },
    "additionalProperties": false
  }
}
```

## Shared contracts

- [Refusals](/reference/refusals): every refusal, by surface, with its cause and its remedy
- [schemas/wire\_error\.schema\.json](/reference/sources/schemas/wire-error-schema)
- [schemas/wire\_errors\.json](/reference/sources/schemas/wire-errors)
- [schemas/action\_payloads\.json](/reference/sources/schemas/action-payloads) (includes shared shapes)
- [management\_api\_contract\.md](/reference/sources/management-api-contract)
