# Product Org Updates

> Source: https://docs.trailspark.ai/docs/product-org-updates

## What Product Org Updates Are

Product Org Updates let you send product workspace/tenant data to TrailSpark via a dedicated webhook endpoint. This is designed for PLG companies that want to incorporate account-level product data into lead scoring -- plan tiers, user counts, MRR, trial status, feature adoption, and custom metrics.

## Webhook Endpoint

```
POST https://app.trailspark.ai/api/product-orgs/webhook/{apiKey}
```

The API key must be created with **Product Org Updates** endpoint type.

## Creating a Product Org API Key

1. Go to **Settings** > **API Keys** > **Create API Key**
2. Select **Product Org Updates** as the endpoint type
3. Configure the **Payload Template** to map fields from your payload to TrailSpark fields
4. Name the key, optionally set expiration and HMAC secret
5. Click **Create API Key**

> [!WARNING]
> Copy your API key immediately. It is only displayed once.

## Payload Template Configuration

The payload template maps incoming webhook fields to TrailSpark's product org fields using dot-notation paths into your payload.

### Required Fields

| Field | Description | Example Path |
|-------|-------------|--------------|
| **Product Org ID** | Unique workspace/tenant identifier | `workspace_id`, `groupId`, `data.tenant.id` |

### Optional Core Fields

| Field | Description | Example Path |
|-------|-------------|--------------|
| **Name** | Workspace display name | `workspace_name`, `traits.name` |
| **Plan ID** | Internal plan identifier | `plan_id`, `traits.plan` |
| **Plan Name** | Human-readable plan name | `plan_name`, `traits.plan_name` |
| **User Count** | Users in workspace | `user_count`, `traits.employees` |
| **MRR** | Monthly recurring revenue (cents) | `mrr`, `traits.mrr` |
| **Trial Status** | Trial state (active, expired, converted) | `trial_status`, `traits.trial_status` |
| **Last Active At** | Last activity timestamp | `last_active_at`, `activity.last_seen` |
| **Feature Flags** | Enabled features (JSON object) | `feature_flags`, `data.features` |

### Custom Fields

Add any product-specific metrics as key-value pairs:

| Custom Field Name | Payload Path |
|-------------------|--------------|
| `projects_count` | `metrics.total_projects` |
| `api_calls_30d` | `usage.api_calls_last_30_days` |
| `storage_gb` | `usage.storage_gigabytes` |

## Payload Examples

### Flat Structure

```json
{
  "workspace_id": "ws_abc123",
  "workspace_name": "Acme Corp Workspace",
  "plan_id": "plan_pro_annual",
  "plan_name": "Pro Annual",
  "user_count": 47,
  "mrr": 49900,
  "trial_status": "converted",
  "last_active_at": "2024-01-15T10:30:00Z",
  "feature_flags": {"sso_enabled": true, "api_access": true},
  "projects_count": 23,
  "api_calls_30d": 15420
}
```

### Segment Group Call

```javascript
analytics.group("ws_abc123", {
  name: "Acme Corp Workspace",
  plan: "pro",
  plan_name: "Pro Annual",
  employees: 47,
  mrr: 49900,
  trial_status: "converted"
});
```

Segment sends this as:
```json
{
  "type": "group",
  "groupId": "ws_abc123",
  "traits": {
    "name": "Acme Corp Workspace",
    "plan": "pro",
    "plan_name": "Pro Annual",
    "employees": 47,
    "mrr": 49900,
    "trial_status": "converted"
  }
}
```

Template configuration for this payload:

| Field | Path |
|-------|------|
| Product Org ID | `groupId` |
| Name | `traits.name` |
| Plan ID | `traits.plan` |
| Plan Name | `traits.plan_name` |
| User Count | `traits.employees` |
| MRR | `traits.mrr` |
| Trial Status | `traits.trial_status` |

### Nested Structure

```json
{
  "data": {
    "tenant": {"id": "tenant_xyz789", "name": "Enterprise Client"},
    "subscription": {
      "plan_id": "enterprise",
      "plan_name": "Enterprise",
      "mrr_cents": 299900,
      "trial": {"status": "not_applicable"}
    },
    "usage": {"active_users": 156, "last_activity": "2024-01-15T14:22:00Z"}
  }
}
```

## How Product Orgs Connect to Leads

1. **Webhook creates target org**: TrailSpark automatically creates a target organization when a Product Org Update is received
2. **Leads link via productOrgId**: When lead signals include a matching `productOrgId`, the lead is linked to the same target organization
3. **Data appears in evaluation**: Product org data surfaces as `productOrgInfo` in the LLM evaluation context, alongside CRM firmographic data

> [!TIP]
> To link leads to product orgs, include a `productOrgId` field in your lead signals that matches the Product Org ID sent via this webhook.

## Evaluation Context

Product org data appears in evaluation as:

```json
{
  "productOrgInfo": [
    {
      "productOrgId": "ws_abc123",
      "name": "Acme Corp Workspace",
      "planName": "Pro Annual",
      "userCount": 47,
      "mrr": 49900,
      "trialStatus": "converted",
      "featureFlags": {"sso_enabled": true, "api_access": true},
      "customFields": {"projects_count": 23, "api_calls_30d": 15420}
    }
  ]
}
```

## Troubleshooting

**Webhook returns 403** -- The API key was not created with Product Org Updates endpoint type. Create a new key with the correct type.

**Product org not created** -- Verify the payload contains a value at the configured `productOrgId` path. Check for typos in nested path definitions.

**Missing fields in evaluation** -- Verify optional field paths match your actual payload structure.

**Leads not linking to product org** -- Ensure lead signals include `productOrgId` matching the product org's ID exactly (case-sensitive).

## Next Steps

- [API Keys](/docs/api-keys)
- [Webhook Configuration](/docs/webhook-configuration)
- [Creating Signal Mapping](/docs/creating-signal-mapping)