Setting up Product Attribution via the API

Who is this article for?

Developers integrating Product Attribution. For program manager overview, see Rewarding partners based on what customers buy.

Prerequisites

  • Your PartnerStack public key and private key (Settings → API)
  • At least one customer has already been created in PartnerStack
  • Basic auth: Authorization: Basic {base64(public_key:private_key)}

Overview

Product Attribution connects three records:

 
Product Catalog (Product Book)
        ↓
   Product (per customer)
        ↓
   Transaction (with subscription_key)

The external_subscription_key on the Product and the subscription_key on the Transaction must match exactly. Values are case-sensitive.

Step 1: Create your Product Catalog

Define the products your company sells. Create one entry per product. This is a one-time setup.

Endpoint: POST /api/v2/product_book

Required fields:

Field Type Description
name string Display name of the product

Optional fields:

Field Type Description
description string Short description
external_key string Your billing system's product ID

Example request:

POST /api/v2/product_book
Authorization: Basic {credentials}
Content-Type: application/json

{
 "name": "Inbox",
 "description": "Shared team inbox for email",
 "external_key": "stripe_prod_inbox"
}
 

Example response:

{
    "data": {
        "archived": false,
        "company_id": 95746372,
        "created_at": 1775514585468,
        "description": "Shared team inbox for email",
        "external_key": "stripe_prod_inbox",
        "id": null,
        "key": "pbook_G9EVeoB85yungS",
        "name": "Inbox 2",
        "updated_at": 1775514585468
    },
    "message": "Product Book Created",
    "status": 200
}
 

Save the key — you'll use it as product_book_key in the next step.

Step 2: Create a Product for a customer

Define the products your company sells. Create one entry per product. This is a one-time setup.

When a customer purchases a product, create a Product record linking them to your catalog.

Endpoint: POST /api/v2/products

Required fields:

Field Type Description
product_book_key string Key from Step 1
customer_key string PartnerStack customer key
status string trial, active, or churned

Optional fields:

Field Type Description
partnership_key string Partner relationship to credit
stack_key string Individual partner member
external_subscription_key string Billing subscription ID — must match subscription_key in Step 3
amount integer Value in cents
currency string ISO 3-letter code

Example request:

Example request:

POST /api/v2/products
Authorization: Basic {credentials}
Content-Type: application/json

{
  "product_book_key": "pbook_G9EVeoB85yungS",
  "customer_key": "cus_def456",
  "status": "active",
  "amount": 19999,
  "partnership_key": "part_xyz789",
  "external_subscription_key": "stripe_prod_inbox",
  "stack_key": "stck_lCuxlSpfTI0Kgo"
}
 

Example response:

{
    "data": {
        "amount": 19999,
        "click_xid": null,
        "company_id": 95746372,
        "created_at": 1775514895894,
        "currency": null,
        "customer_key": "cus_def456",
        "external_subscription_key": "stripe_prod_inbox",
        "field_data": null,
        "key": "prod_tQofY1CbOSIlIQ",
        "member_email": null,
        "member_logo": null,
        "member_name": null,
        "metadata": null,
        "name": null,
        "partner_logo": null,
        "partner_name": null,
        "partnership_key": "part_xyz789",
        "product_book_key": "pbook_G9EVeoB85yungS",
        "stack_key": "stck_lCuxlSpfTI0Kgo",
        "status": "active",
        "team_color": null,
        "updated_at": 1775514895894
    },
    "message": "Product created successfully",
    "status": 201
}

Edge cases:

  • customer_key doesn't exist → 403 error. Create the customer first.
  • partnership_key doesn't belong to your company → 403 error.
  • stack_key isn't linked to an active partner → silently ignored. No error, but no attribution.

Step 3: Send transactions with a product reference

On each billing event, send a transaction. Include subscription_key to link it to the customer's product.

Endpoint: POST /api/v2/transactions

Required fields:

Field Type Description
amount integer Amount in cents
currency string ISO 3-letter code
customer_key or customer_external_key or customer_email string Identifies the customer (provide one)

For product attribution:

Field Type Description
subscription_key string Must match external_subscription_key from Step 2

Example request:

POST /api/v2/transactions
Authorization: Basic {credentials}
Content-Type: application/json

{
  "amount": 9900,
  "currency": "USD",
  "customer_key": "cus_def456",
  "subscription_key": "pbook_G9EVeoB85yungS"
}

What happens:

  1. PartnerStack looks for a Product where external_subscription_key matches
  2. If found: transaction is linked to that product — product data is available for trigger rules
  3. If not found: transaction is created but without product data — no error returned

Verifying your integration

After sending a transaction with subscription_key:

  1. Retrieve it via GET /api/v2/transactions?customer_key={cus_key}
  2. Check that product_key is populated
  3. If null, the subscription_key didn't match any product — check for case mismatches

You can also check the customer's Products tab in the PartnerStack dashboard to confirm the product appears with the correct status.


Field reference

Product status values:

Value Meaning
trial Customer is in trial
active Active paid subscription
churned Cancelled or lapsed

If you need help integrating, reach out to support@partnerstack.com or your Customer Success Manager.

 

Related articles: