Skip to main content

Product Tables

Product tables allow you to include structured pricing information in your documents. They’re ideal for quotes, invoices, order forms, and any document that needs to present products or services with pricing.

Overview

A product table displays:
  • Products/Services with descriptions
  • Quantities for each line item
  • Unit prices and calculated totals
  • Subtotals, VAT, and grand totals
Product table in a document showing line items with prices and totals

Creating Product Table Fields

Product tables are added as document fields. First, create a document, then add a product table field.

Add a Product Table to a Document

curl -X POST https://app.sajn.se/api/v1/documents/doc_123/fields \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "PRODUCT_TABLE",
    "page": 1,
    "position": {
      "x": 50,
      "y": 300,
      "width": 500,
      "height": 200
    },
    "fieldMeta": {
      "products": [
        {
          "name": "Website Design",
          "description": "Custom website design and development",
          "quantity": 1,
          "unitPrice": 25000,
          "unit": "st"
        },
        {
          "name": "Hosting (Annual)",
          "description": "Web hosting for one year",
          "quantity": 1,
          "unitPrice": 3600,
          "unit": "year"
        },
        {
          "name": "Support Hours",
          "description": "Technical support and maintenance",
          "quantity": 10,
          "unitPrice": 950,
          "unit": "hour"
        }
      ],
      "currency": "SEK",
      "vatRate": 25,
      "showVat": true
    }
  }'

Table Structure

Product table configuration interface showing field options

Product Line Item Fields

FieldTypeRequiredDescription
namestringYesProduct or service name
descriptionstringNoDetailed description
quantitynumberYesNumber of units
unitPricenumberYesPrice per unit (in minor currency units or major)
unitstringNoUnit type (e.g., “st”, “hour”, “month”)
discountnumberNoDiscount percentage for this line

Table Configuration

FieldTypeDescription
currencystringCurrency code (e.g., “SEK”, “EUR”, “USD”)
vatRatenumberVAT/tax percentage (e.g., 25 for 25%)
showVatbooleanWhether to display VAT separately
includesVatbooleanWhether prices include VAT
columnsarrayCustom column configuration

Calculations

Product tables automatically calculate:

Line Item Total

lineTotal = quantity × unitPrice × (1 - discount/100)

Subtotal

subtotal = sum of all lineTotals

VAT Amount

vatAmount = subtotal × (vatRate / 100)

Grand Total

grandTotal = subtotal + vatAmount

Example Calculation

For the example above:
ProductQuantityUnit PriceLine Total
Website Design125,000 SEK25,000 SEK
Hosting (Annual)13,600 SEK3,600 SEK
Support Hours10950 SEK9,500 SEK
Amount
Subtotal38,100 SEK
VAT (25%)9,525 SEK
Grand Total47,625 SEK

Complete Example: Quote Document

Create a quote with product table, signers, and custom fields:
# Step 1: Create the document
curl -X POST https://app.sajn.se/api/v1/documents \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Quote - Website Project for Acme Corp",
    "type": "SIGNABLE",
    "expiresAt": "2024-02-28T23:59:59Z",
    "documentMeta": {
      "subject": "Quote for your website project",
      "message": "Please review our quote and sign to accept."
    },
    "signers": [
      {
        "name": "Anna Andersson",
        "email": "anna@acme.se",
        "role": "SIGNER",
        "deliveryMethod": "EMAIL",
        "requiredSignature": "DRAWING"
      }
    ],
    "customFields": [
      {
        "key": "quote_number",
        "value": "Q-2024-0042"
      },
      {
        "key": "valid_until",
        "value": "2024-02-28"
      }
    ]
  }'
# Step 2: Add the product table
curl -X POST https://app.sajn.se/api/v1/documents/doc_123/fields \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "PRODUCT_TABLE",
    "page": 1,
    "position": {
      "x": 50,
      "y": 250,
      "width": 500,
      "height": 250
    },
    "fieldMeta": {
      "products": [
        {
          "name": "Discovery & Planning",
          "description": "Requirements gathering and project planning",
          "quantity": 1,
          "unitPrice": 15000
        },
        {
          "name": "UI/UX Design",
          "description": "User interface and experience design",
          "quantity": 1,
          "unitPrice": 35000
        },
        {
          "name": "Frontend Development",
          "description": "React-based frontend implementation",
          "quantity": 1,
          "unitPrice": 45000
        },
        {
          "name": "Backend Development",
          "description": "API and database development",
          "quantity": 1,
          "unitPrice": 55000
        },
        {
          "name": "Testing & QA",
          "description": "Quality assurance and testing",
          "quantity": 1,
          "unitPrice": 15000
        }
      ],
      "currency": "SEK",
      "vatRate": 25,
      "showVat": true
    }
  }'

Styling Product Tables

Column Configuration

Customize which columns appear and their order:
{
  "fieldMeta": {
    "columns": [
      { "key": "name", "label": "Product", "width": 200 },
      { "key": "description", "label": "Description", "width": 150 },
      { "key": "quantity", "label": "Qty", "width": 50 },
      { "key": "unitPrice", "label": "Unit Price", "width": 80 },
      { "key": "lineTotal", "label": "Total", "width": 80 }
    ],
    "products": [...]
  }
}

Formatting Options

{
  "fieldMeta": {
    "currency": "SEK",
    "currencySymbol": "kr",
    "currencyPosition": "after",
    "decimalPlaces": 2,
    "thousandsSeparator": " ",
    "decimalSeparator": ","
  }
}
This formats prices as: 25 000,00 kr

Use Cases

Quotes and Proposals

Present pricing for proposed work with clear line items:
{
  "products": [
    { "name": "Consulting", "quantity": 40, "unitPrice": 1500, "unit": "hours" },
    { "name": "Implementation", "quantity": 1, "unitPrice": 75000, "unit": "project" },
    { "name": "Training", "quantity": 2, "unitPrice": 15000, "unit": "days" }
  ]
}

Invoices

Bill for delivered goods or services:
{
  "products": [
    { "name": "Product A", "quantity": 100, "unitPrice": 150 },
    { "name": "Product B", "quantity": 50, "unitPrice": 299 },
    { "name": "Shipping", "quantity": 1, "unitPrice": 500 }
  ]
}

Order Forms

Allow customers to sign off on orders:
{
  "products": [
    { "name": "Annual License", "quantity": 10, "unitPrice": 9990, "unit": "users" },
    { "name": "Premium Support", "quantity": 1, "unitPrice": 25000, "unit": "year" },
    { "name": "Onboarding", "quantity": 1, "unitPrice": 15000 }
  ]
}

Service Agreements

Define service packages and pricing:
{
  "products": [
    { "name": "Basic Plan", "description": "Core features", "quantity": 12, "unitPrice": 999, "unit": "months" },
    { "name": "Setup Fee", "quantity": 1, "unitPrice": 5000 },
    { "name": "API Access", "quantity": 12, "unitPrice": 500, "unit": "months" }
  ]
}

Updating Product Tables

Update Products

Modify the product list on an existing field:
curl -X PATCH https://app.sajn.se/api/v1/documents/doc_123/fields/field_456 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "fieldMeta": {
      "products": [
        {
          "name": "Updated Product",
          "quantity": 5,
          "unitPrice": 1000
        }
      ]
    }
  }'
Product tables can only be modified while the document is in draft status. Once sent for signing, the table is locked.

Best Practices

Product names should be immediately understandable. Avoid internal codes or abbreviations that signers won’t recognize.
Use the description field to clarify what’s included in each line item, especially for services.
In B2B contexts, buyers often need to see VAT separately for accounting. Enable showVat: true.
Ensure the currency matches your business context and is clearly displayed.
Double-check that calculated totals match your expectations before sending the document.
For quotes and proposals, consider adding text fields with payment terms, validity period, and conditions.

Next Steps

Creating Documents

Learn document creation basics

Templates and Forms

Create reusable templates with product tables

Document Fields API

Full field API documentation

Send for Signing

Send documents to signers