invite_guest

Invite a guest from a document

act entity controlled-share since 2026-10-01

Invites the person behind one of a document's parties, by email address, as a guest of the org that owns the document. A guest signs in with their own login and reads the documents their party holds a seat on in that org, and nothing else of it: a lessee (a forwarder) reads its leases, a seller (a supplier) its purchase orders. Inviting the same person again for the same party changes nothing. A current member of the org, a guest of it for another party, a deactivated user, and a party that is already a Trade HQ org are refused. An optional expires_on, from today to 365 days out, is the guest's last day of access; from the next day they are refused as a revoked guest is.

Contract

shape
entity
authority
act
evidence
none
subscription
false
permission
any one of: staff.ops (the staff role staff_ops held in the Internal org, tradehq_role.staff_role); org.admin (carried by the caller's role template in the org `org_id`, which owns the document `document_kind`/`document_id`); a deactivated caller is refused first
idempotency
natural
emits
guest.invited
MCP tool
invite_guest
decision_set
approve, reject, edit, request_info
REST
POST https://api.containertradehq.com/v1/cap/invite_guest

Through MCP this call returns an approval request first; see Approvals.

Idempotency: keyed by the contract's own inputs: the same inputs replay the first call's result

Inputs

nametyperequiredvalidation
org_idorg_idrequiredtradehq-org-id; 1 to 20 characters
The org that owns the document, and that the guest becomes a guest of.
document_kindone_ofrequiredone of asset_intake, order
The document the invitation is made from: an order (a lease) for a lessee, an asset_intake (a purchase order) for a seller.
document_idtextrequired1 to 64 characters
The document's id in that table.
party_iduuidrequiredUUID
The party on the document the guest is, from the shared directory.
seatone_ofrequiredone of lessee, seller
The seat that party holds on the document: lessee or seller.
emailemailrequiredemail address; 3 to 254 characters
The guest's email address. It becomes their sign-in.
nametextoptional1 to 255 characters
Their full name, set only if they have none yet.
expires_ondateoptionaldate, YYYY-MM-DD
The guest's last day of access, a UTC date from today to 365 days out. Absent, their access does not expire.

Response

  • user_id · string · The guest.
  • org_id · string · The org they are a guest of.
  • email · value · The address, cleaned.
  • party_id · string · The party they are.
  • seat · string · Their seat.
  • role_id · string · The Counterparty template they hold: counterparty_<seat>.
  • shape · string · What their view shows: forwarder (leases) or supplier (purchase orders).
  • expires_on · stringnull · Their last day of access, or null for none. A repeat invitation answers the expiry the guest holds.
Full JSON Schema
{
  "type": "object",
  "properties": {
    "user_id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 20,
      "pattern": "^[A-Za-z0-9_-]{1,20}$",
      "format": "tradehq-user-id",
      "description": "The guest.",
      "x-data-class": "operational"
    },
    "org_id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 20,
      "pattern": "^[A-Za-z0-9_-]{1,20}$",
      "format": "tradehq-org-id",
      "description": "The org they are a guest of.",
      "x-data-class": "operational"
    },
    "email": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "const": "•••",
          "description": "Masked by the caller's data policy."
        },
        {
          "type": "null",
          "description": "Denied by the caller's data policy."
        }
      ],
      "description": "The address, cleaned.",
      "x-data-class": "personal"
    },
    "party_id": {
      "type": "string",
      "pattern": "^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$",
      "format": "uuid",
      "description": "The party they are.",
      "x-data-class": "operational"
    },
    "seat": {
      "type": "string",
      "enum": [
        "lessee",
        "seller"
      ],
      "description": "Their seat.",
      "x-data-class": "operational"
    },
    "role_id": {
      "type": "string",
      "description": "The Counterparty template they hold: counterparty_<seat>.",
      "x-data-class": "operational"
    },
    "shape": {
      "type": "string",
      "enum": [
        "forwarder",
        "supplier"
      ],
      "description": "What their view shows: forwarder (leases) or supplier (purchase orders).",
      "x-data-class": "operational"
    },
    "expires_on": {
      "type": [
        "string",
        "null"
      ],
      "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$",
      "format": "date",
      "description": "Their last day of access, or null for none. A repeat invitation answers the expiry the guest holds.",
      "x-data-class": "operational"
    }
  },
  "required": [
    "user_id",
    "org_id",
    "email",
    "party_id",
    "seat",
    "role_id",
    "shape",
    "expires_on"
  ],
  "additionalProperties": false
}

Refusals

not yet declared

The platform refusals apply to every call: version, authentication, authority, validation and rate limits, each in the same envelope.

Surfaces

DesktopF
MobileF
APIF
MCPF*
VoiceD2
PushF
OneBoxN
OutboundF
  • MCP: approval required
  • Voice: degraded: confirmation
  • OneBox: an invitation is made by a person reading the document, never by an inbound one

Events

Related

add_file, claim_party, create_data_share, create_upload, list_data_shares, list_document_parties, preview_data_share, set_document_parties