Organization Account Integration and Customization Guide

Step‐by‐step reference for creating and managing organization child accounts and customizing their settings. It covers the entire workflow—from creating a child account and associating it into your organization’s hierarchy to leveraging inheritance, managing sessions via impersonation, and updating customization settings.

1. Overview

An Organization Child Account is a Wingspan User Account created under a parent account. This hierarchical model lets you structure your organization into nodes (for example, departments or business units) and automatically inherit configuration settings from a parent account. Iit is strongly recommended that you limit the nesting depth to two or three levels for clarity, maintainability, and optimal performance.

2. Creating and Associating an Organization Child Account

This section details the two-step process to create a new child account and integrate it into your organizational hierarchy.

2.1 Create the Child Account

Endpoint:
POST /users/organization/user

Headers:

  • Accept: application/json
  • Content-Type: application/json
  • Authorization: Bearer {master_token}
  • (Optional) X-WINGSPAN-USER: {parent_user_id} – used to indicate the initiating node.

Purpose:
Creates a new user account that is “owned” by the creator. Until the account is associated with a parent node, it exists independently and does not inherit any parent settings.

Sample Request Body:

{
  "email": "contractor.jane@example.com",
  "profile": {
    "firstName": "Jane",
    "lastName": "Doe"
  },
}

2.2 Associate the Child Account with Your Organization

Endpoint:
POST /users/organization/user/{child_user_id}/associate

Headers:

  • Accept: application/json
  • Content-Type: application/json
  • Authorization: Bearer {master_token}

Purpose:
This endpoint links the newly created child account to your organization’s hierarchy by designating it as a child of an existing parent node. Once associated, the account appears in the organization tree and becomes eligible for configuration inheritance according to the defined strategy.

Sample Request Body:

{
  "parentUserId": "parent_123456",
  "inheritanceStrategy": {
    "organizationAccountConfig": "Parent",
    "wingspanAccount": "Parent"
  }
}

Explanation:

  • parentUserId: Specifies the unique identifier of the parent node under which the new account will be placed.

  • inheritanceStrategy: An object that defines the inheritance behavior for specific properties. Each field within this object is an enum that accepts one of two values: "None" or "Parent".

    • organizationAccountConfig:
      • Purpose: Determines if the child account should inherit customization settings (e.g., branding, email templates, support information) from its parent.
      • Allowed Values: "Parent" (to inherit the parent's customization settings) or "None" (to use only the child’s own settings).
    • wingspanAccount:
      • Purpose: Determines if the child account should inherit account-related configurations (e.g., payment, payroll, and payout methods) from its parent.
      • Allowed Values: "Parent" (to inherit the parent's account configurations) or "None" (to use only the child’s own configurations).

Note:
Other fields within the inheritance strategy are placeholders for future use and are not included in this example. If no inheritance properties are provided, each field defaults to "None", meaning no inheritance occurs.

3. Inheritance Behavior and Session Impersonation

3.1 Inheritance Behavior

Inheritance automatically merges configuration settings from a parent account into a child account in order to maintain consistency across your organization. The merge process works as follows:

  • Merging Configuration Values: The system gathers configuration settings from both the child account and its parent account(s. These objects are then deep-merged (using a recursive merge approach) so that nested objects are combined field-by-field.

  • Override Rules Using Truthy Values Only:
    During the merge, only fields that have “truthy” values (i.e. values that are neither false, empty strings, nor null) in the merged result are applied to the child account. This means:

    • If a configuration field is not provided on the child (or its merged value calculates as falsey), the corresponding value inherited from the parent is used.
    • Important: An override on the child account only takes effect if the override value is truthy. If a child explicitly sets a field to an empty string, null, or any other falsey value, that override is ignored, and the parent’s value remains active.
  • Default Behavior:
    When no inheritance settings are provided (i.e. the default inheritance strategy is “None”), the child account retains only its own explicitly stored values without any merging from its parent.

Use-Case Example:
Consider a scenario where a parent account has defined its branding as follows:

{
  "branding": {
    "name": "Acme Corp",
    "primaryLogoUrl": "https://example.com/logos/primary.png",
    "secondaryLogoUrl": "https://example.com/logos/secondary.png",
    "url": "https://acme.example.com"
  }
}
  • If a child account is associated with the parent and provides no explicit configuration overrides, a GET request for its customization settings will display the parent’s branding values.
  • If the child account later provides a new, truthy value for only primaryLogoUrl, then that field is overridden while all other branding fields remain inherited from the parent.
  • If the child account attempts to override a field by providing a falsey value (for example, setting name to an empty string or null), that falsey value is ignored, and the inherited parent’s value for name continues to be used.

3.2 Session Management and Impersonation

There are two primary approaches for executing API actions on behalf of a child account:

  1. Child Account Session Creation:
    Use the endpoint:
    GET /users/organization/user/{child_user_id}/session

  2. Impersonation via the X-WINGSPAN-USER Header (Recommended for API Integrations):
    Use your master token along with the header:

    X-WINGSPAN-USER: child_98765
    

    Benefits:

    • Simplifies token management by using a single master token.
    • Avoids the overhead of managing multiple sessions.
    • Ensures that your master token has the necessary permissions to impersonate the child account.

4. Customization Endpoints

Customization endpoints allow you to retrieve and update visual and operational settings for an organization user. These settings include branding, email templates, organization-specific defaults, support information, and terminology.

4.1 GET /users/customization/{id}

Purpose:
Fetches the current, merged customization settings for the specified user. The response reflects both the user’s own configuration and any inherited values from the parent account.

Endpoint:
GET /users/customization/{id}

Headers:

  • Accept: application/json
  • Content-Type: application/json
  • Authorization: Bearer {master_token}

Sample Response Body:

{
  "createdAt": "2025-02-01T10:00:00.000Z",
  "updatedAt": "2025-02-03T15:00:00.000Z",
  "branding": {
    "name": "Acme Corp",
    "primaryLogoUrl": "https://example.com/logos/primary.png",
    "secondaryLogoUrl": "https://example.com/logos/secondary.png",
    "url": "https://acme.example.com"
  },
  "emailCustomization": {
    "footerSnippet": "Thank you for choosing Acme Corp!",
    "logo": {
      "logoLogomarkSrc": "https://example.com/email/logo-logomark.png",
      "logoWordmarkSrc": "https://example.com/email/logo-wordmark.png"
    },
    "styles": {
      "fontFamily": "Arial, sans-serif",
      "color": "#333333"
    },
    "templates": {
      "contractorInvite": {
        "payerMessageSnippet": "Welcome aboard! Please complete your setup."
      }
    }
  },
  "organizationSettings": {
    "defaultNewPayeeParentAccountId": "org_parent_001",
    "defaultNewPayerParentAccountId": "org_parent_002"
  },
  "support": {
    "documentation": {
      "generalUrl": "https://support.acme.example.com/docs",
      "payoutInformationUrl": "https://support.acme.example.com/payouts"
    },
    "portal": {
      "generalUrl": "https://support.acme.example.com/portal"
    },
    "generalSupportEmail": "support@acme.example.com",
    "payeeSupportEmail": "contractorsupport@acme.example.com",
    "payerSupportEmail": "clientsupport@acme.example.com"
  }
}

Field Descriptions

  • branding: Visual identity elements such as company name, logos, and website URL.
  • emailCustomization: Settings for email styling and formatting (footer text, logo images, styles, and templates).
  • organizationSettings:
    • defaultNewPayeeParentAccountId: Automatically associates new payee (contractor) accounts as children of the specified parent account.
    • defaultNewPayerParentAccountId: Automatically associates new payer (client) accounts as children of the specified parent account.
  • support: Provides support documentation URLs and contact email addresses.

4.2 PATCH /users/customization/{id}

Purpose:
Updates the customization settings for the specified user. This PATCH operation merges the provided fields with existing settings so that only explicitly supplied fields override current values.

Endpoint:
PATCH /users/customization/{id}

Headers:

  • Accept: application/json
  • Content-Type: application/json
  • Authorization: Bearer {master_token}

Update Process

  1. Retrieve Current Settings: Use the GET endpoint (GET /users/customization/{id}) to review the current configuration.

  2. Prepare the Update Payload:Include only the fields you wish to change. For example, to update branding and default associations:

    Sample Request Body:

    {
      "branding": {
        "primaryLogoUrl": "https://example.com/logos/updated_primary.png",
        "name": "Acme Corporation Updated"
      },
      "organizationSettings": {
        "defaultNewPayeeParentAccountId": "org_parent_003",
        "defaultNewPayerParentAccountId": "org_parent_004"
      },
      "emailCustomization": {
        "footerSnippet": "We appreciate your business at Acme Corp."
      }
    }
    
  3. Merge Behavior:

    • Fields provided in the PATCH override any inherited or existing values.
    • Fields omitted remain unchanged or continue to be inherited from the parent.
    • Example: If a child account updates its primary logo but omits the secondary logo, the secondary logo remains as set previously or as inherited from the parent.
  4. Submit and Verify: After submitting the PATCH request, verify the update with a subsequent GET call.

Sample Response Body (After Successful Update):

{
  "createdAt": "2025-02-01T10:00:00.000Z",
  "updatedAt": "2025-02-04T11:30:00.000Z",
  "branding": {
    "name": "Acme Corporation Updated",
    "primaryLogoUrl": "https://example.com/logos/updated_primary.png",
    "secondaryLogoUrl": "https://example.com/logos/secondary.png",
    "url": "https://acme.example.com"
  },
  "emailCustomization": {
    "footerSnippet": "We appreciate your business at Acme Corp!",
    "logo": {
      "logoLogomarkSrc": "https://example.com/email/logo-logomark.png",
      "logoWordmarkSrc": "https://example.com/email/logo-wordmark.png"
    },
    "styles": {
      "fontFamily": "Arial, sans-serif",
      "color": "#333333"
    },
    "templates": {
      "contractorInvite": {
        "payerMessageSnippet": "Welcome aboard! Please complete your setup."
      }
    }
  },
  "organizationSettings": {
    "defaultNewPayeeParentAccountId": "org_parent_003",
    "defaultNewPayerParentAccountId": "org_parent_004"
  },
  "support": {
    "documentation": {
      "generalUrl": "https://support.acme.example.com/docs",
      "payoutInformationUrl": "https://support.acme.example.com/payouts"
    },
    "portal": {
      "generalUrl": "https://support.acme.example.com/portal"
    },
    "generalSupportEmail": "support@acme.example.com",
    "payeeSupportEmail": "contractorsupport@acme.example.com",
    "payerSupportEmail": "clientsupport@acme.example.com"
  },
}

5. Best Practices and Recommendations

  • Two-Step Process for Account Integration:

    1. Create the Child Account: Use POST /users/organization/user to generate a new account.
    2. Associate the Account: Immediately link the account using POST /users/organization/user/{child_user_id}/associate so that it becomes part of your organizational hierarchy and inherits settings as configured.
  • Nesting Depth: Limit the organizational tree to two or three levels. Although unlimited nesting is technically supported, deeper hierarchies can complicate management and reduce performance.

  • Session Management and Impersonation:

    • For API integrations, use your master token with the X-WINGSPAN-USER header (e.g., X-WINGSPAN-USER: child_98765) rather than creating separate sessions.
    • This simplifies token management and reduces overhead—ensure your master token has the necessary permissions to impersonate the child account.
  • Default Associations in OrganizationSettings:

    • Configure the fields defaultNewPayeeParentAccountId and defaultNewPayerParentAccountId to automatically associate new payee (contractor) or payer (client) accounts with a specified parent account.
    • Example: If your primary contractor management node has the ID org_parent_001, set defaultNewPayeeParentAccountId to org_parent_001 so that any new contractor account is automatically linked to that node.