Skip to main content
Glama

create_embedded_invite

Generate embedded signing invites for documents or document groups to collect signatures directly within applications.

Instructions

Create embedded invite for signing a document or document group. This tool is ONLY for documents and document groups. If you have template or template_group, use the alternative tool: create_embedded_invite_from_template

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
entity_idYesID of the document or document group
ordersNoList of orders with recipients (can be a list or JSON string)
entity_typeNoType of entity: 'document' or 'document_group' (optional). If you're passing it, make sure you know what type you have. If it's not found, try using a different type.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
invite_idYesID of the created embedded invite
invite_entityYesType of invite entity: 'document' or 'document_group'
recipient_linksYesArray of objects with role and link for recipients with delivery_type='link'

Implementation Reference

  • MCP tool registration and handler for 'create_embedded_invite'. Decorated with @mcp.tool, processes inputs including orders normalization, retrieves auth token and client, and calls the core helper function.
        name="create_embedded_invite",
        description=(
            "Create embedded invite for signing a document or document group. "
            "This tool is ONLY for documents and document groups. "
            "If you have template or template_group, use the alternative tool: create_embedded_invite_from_template"
        ),
        tags=["send_invite", "document", "document_group", "sign", "embedded", "workflow"],
    )
    def create_embedded_invite(
        ctx: Context,
        entity_id: Annotated[str, Field(description="ID of the document or document group")],
        orders: Annotated[
            list[EmbeddedInviteOrder] | str | None,
            Field(
                description="List of orders with recipients (can be a list or JSON string)",
                examples=[
                    [{"order": 1, "recipients": [{"email": "user@example.com", "role": "Signer 1", "action": "sign", "auth_method": "none"}]}],
                    '[{"order": 1, "recipients": [{"email": "user@example.com", "role": "Signer 1", "action": "sign", "auth_method": "none"}]}]',
                ],
            ),
        ] = None,
        entity_type: Annotated[
            Literal["document", "document_group"] | None,
            Field(description="Type of entity: 'document' or 'document_group' (optional). If you're passing it, make sure you know what type you have. If it's not found, try using a different type."),
        ] = None,
    ) -> CreateEmbeddedInviteResponse:
        """Create embedded invite for signing a document or document group.
    
        This tool is ONLY for documents and document groups.
        If you have template or template_group, use the alternative tool: create_embedded_invite_from_template
    
        Args:
            entity_id: ID of the document or document group
            orders: List of orders with recipients (can be a list or JSON string)
            entity_type: Type of entity: 'document' or 'document_group' (optional). If you're passing it, make sure you know what type you have. If it's not found, try using a different type.
    
        Returns:
            CreateEmbeddedInviteResponse with invite ID and entity type
        """
        token, client = _get_token_and_client(token_provider)
    
        # Normalize orders parameter (handle JSON string input)
        normalized_orders = _normalize_orders(orders, EmbeddedInviteOrder)
    
        # Initialize client and use the imported function from embedded_invite module
        return _create_embedded_invite(entity_id, entity_type, normalized_orders, token, client)
  • Output schema: CreateEmbeddedInviteResponse defining the return type of the tool.
    class CreateEmbeddedInviteResponse(BaseModel):
        """Response model for creating embedded invite."""
    
        invite_id: str = Field(..., description="ID of the created embedded invite")
        invite_entity: str = Field(..., description="Type of invite entity: 'document' or 'document_group'")
        recipient_links: list[dict[str, str]] = Field(..., description="Array of objects with role and link for recipients with delivery_type='link'")
  • Input schema component: EmbeddedInviteOrder used for the 'orders' parameter structure.
    class EmbeddedInviteOrder(BaseModel):
        """Order information for embedded invite."""
    
        order: int = Field(..., description="Order number for this step")
        recipients: list[EmbeddedInviteRecipient] = Field(..., description="List of recipients for this order")
  • Core helper function implementing the logic to create embedded invite: auto-detects entity type, validates orders, and routes to document or document_group specific helpers which call the SignNow client.
    def _create_embedded_invite(
        entity_id: str, entity_type: Literal["document", "document_group"] | None, orders: list[EmbeddedInviteOrder], token: str, client: SignNowAPIClient
    ) -> CreateEmbeddedInviteResponse:
        """Private function to create embedded invite for signing a document or document group.
    
        Args:
            entity_id: ID of the document or document group
            entity_type: Type of entity: 'document' or 'document_group' (optional). If you're passing it, make sure you know what type you have. If it's not found, try using a different type.
            orders: List of orders with recipients
            token: Access token for SignNow API
            client: SignNow API client instance
    
        Returns:
            CreateEmbeddedInviteResponse with invite ID and entity type
        """
        # Determine entity type if not provided
        document_group = None  # Store document group if found during auto-detection
    
        if not entity_type:
            # Try to determine entity type by attempting to get document group first (higher priority)
            try:
                document_group = client.get_document_group(token, entity_id)
                entity_type = "document_group"
            except Exception:
                # If document group not found, try document
                try:
                    client.get_document(token, entity_id)
                    entity_type = "document"
                except Exception:
                    raise ValueError(f"Entity with ID {entity_id} not found as either document group or document") from None
    
        # Validate orders
        if not orders:
            raise ValueError("At least one order with recipients is required")
    
        if entity_type == "document_group":
            # Create document group embedded invite
            # Get the document group if we don't have it yet
            if not document_group:
                document_group = client.get_document_group(token, entity_id)
    
            return _create_document_group_embedded_invite(client, token, entity_id, orders, document_group)
        else:
            # Create document embedded invite
            return _create_document_embedded_invite(client, token, entity_id, orders)
  • SignNow API client method called by helpers to create the embedded invite via HTTP POST to the SignNow API.
    def create_embedded_invite(self, token: str, document_group_id: str, request_data: CreateEmbeddedInviteRequest) -> EmbeddedInviteResponse:
        """
        Create embedded signing invite for a document group.
    
        This endpoint allows users to create an embedded signing invite for a document group.
        Once the invite is created, generate an embedded signing link using the invite ID.
    
        Args:
            token: Access token for authentication
            document_group_id: ID of the document group
            request_data: Embedded invite request data with signers and documents
    
        Returns:
            Validated EmbeddedInviteResponse model with the created invite ID
    
        Raises:
            SignNowAPIError: When current user is not the document group owner
            SignNowAPIError: When document group has no document with fields
            SignNowAPIError: When document group has active invites
            SignNowAPIError: When role doesn't exist in the document
            SignNowAPIError: When not all document roles were used
            SignNowAPIError: When document owner's email was used as signer's email
        """
    
        headers = {"Accept": "application/json", "Content-Type": "application/json", "Authorization": f"Bearer {token}"}
    
        return self._post(
            f"/v2/document-groups/{document_group_id}/embedded-invites",
            headers=headers,
            json_data=request_data.model_dump(exclude_none=True),
            validate_model=EmbeddedInviteResponse,
        )
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It states the tool creates an embedded invite, implying a write operation, but doesn't mention permissions, rate limits, or what the output contains. The description adds basic context about the tool's scope but lacks details on behavioral traits like authentication requirements or response format.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with zero waste: the first states the purpose and scope, the second provides explicit usage guidance. It's front-loaded with the core functionality and efficiently addresses sibling tool differentiation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 3 parameters, 100% schema coverage, and an output schema (which handles return values), the description is reasonably complete. It clearly defines the tool's purpose and usage context. However, with no annotations, it could benefit from mentioning behavioral aspects like permissions or rate limits, though the output schema reduces the need for return value explanation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all parameters thoroughly. The description doesn't add any parameter-specific information beyond what's in the schema, but it does reinforce the entity_type constraints ('documents and document groups'), which aligns with the schema's enum values. Baseline 3 is appropriate when schema coverage is complete.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('Create embedded invite') and resource ('for signing a document or document group'), and explicitly distinguishes it from sibling tools by specifying 'ONLY for documents and document groups' and naming the alternative tool for templates.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance on when to use this tool ('ONLY for documents and document groups') and when to use an alternative ('If you have template or template_group, use the alternative tool: create_embedded_invite_from_template'), clearly differentiating it from siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/signnow/sn-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server